umlet-2015-06-03_UMLet_v13.3/0000755000175000017500000000000012533641120013223 5ustar benbenumlet-2015-06-03_UMLet_v13.3/README.md0000644000175000017500000000057612533641120014512 0ustar benben# UMLet UMLet is an open-source UML tool with a simple user interface: draw UML diagrams fast, export diagrams to eps, pdf, jpg, svg, and clipboard, share diagrams using Eclipse, and create new, custom UML elements. * Please check out the [Wiki](https://github.com/umlet/umlet/wiki) for frequently asked questions * Go to http://www.umlet.com to get the latest compiled versions umlet-2015-06-03_UMLet_v13.3/BaseletElements/0000755000175000017500000000000012537353206016310 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/0000755000175000017500000000000012533641120017256 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/0000755000175000017500000000000012533641120020034 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/0000755000175000017500000000000012533641120021453 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/element/0000755000175000017500000000000012533641120023104 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/element/sticking/0000755000175000017500000000000012533641120024717 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/element/sticking/StickablesTest.java0000644000175000017500000001062412533641120030511 0ustar benbenpackage com.baselet.element.sticking; import static org.junit.Assert.assertEquals; import org.junit.Test; import com.baselet.control.basics.geom.PointDouble; import com.baselet.element.sticking.StickingPolygon.StickLine; public class StickablesTest { @Test public void moveLineLeft40_pointLeft40() throws Exception { PointChange change = calcChange(point(20, 20), vLine(20, 10, 30), -40, 0); assertPoint(-40, 0, change); } @Test public void moveLineRight40_pointRight40() throws Exception { PointChange change = calcChange(point(20, 20), vLine(20, 10, 30), 40, 0); assertPoint(40, 0, change); } @Test public void moveLineUp40_pointUp40() throws Exception { PointChange change = calcChange(point(20, 20), hLine(10, 30, 20), 0, -40); assertPoint(0, -40, change); } @Test public void moveLineLeftDown40_pointLeftDown40() throws Exception { PointChange change = calcChange(point(20, 20), hLine(10, 30, 20), 40, 40); assertPoint(40, 40, change); } @Test public void moveLineRightDown10_pointRightDown10() throws Exception { PointChange change = calcChange(point(20, 20), vLine(20, 10, 30), 10, 10); assertPoint(10, 10, change); } @Test public void resizeLineVertical_pointStaysSame() throws Exception { PointChange change = calcChange(point(20, 20), vLine(20, 10, 80), vLine(20, 10, 20)); assertPoint(0, 0, change); } @Test public void resizeLineVertical_pointMovesToLowerEnd() throws Exception { PointChange change = calcChange(point(20, 70), vLine(20, 10, 80), vLine(20, 10, 30)); assertPoint(0, -40, change); } @Test public void resizeLineHorizontal_pointStaysOnLeftEnd() throws Exception { PointChange change = calcChange(point(20, 50), hLine(20, 150, 50), hLine(100, 150, 50)); assertPoint(80, 0, change); } @Test public void resizeLineVertical_pointStaysOnUpperEnd() throws Exception { PointChange change = calcChange(point(20, 50), vLine(20, 50, 200), vLine(20, 150, 200)); assertPoint(0, 100, change); } @Test public void resizeLineHorizontal_pointStaysSame() throws Exception { PointChange change = calcChange(point(20, 50), hLine(20, 150, 50), hLine(100, 150, 50)); assertPoint(80, 0, change); } @Test public void moveHorizontalResizeVertical_pointMovesHorizontalAndStaysSameVertical() throws Exception { PointChange change = calcChange(point(100, 100), vLine(100, 10, 200), vLine(60, 10, 150)); assertPoint(-40, 0, change); } @Test public void moveHorizontalResizeVertical_pointMovesHorizontalAndMovesToEndVertical() throws Exception { PointChange change = calcChange(point(50, 50), vLine(50, 10, 200), vLine(100, 10, 30)); assertPoint(50, -20, change); } @Test public void moveVerticalResizeHorizontal_pointMovesVerticalAndStaysSameHorizontal() throws Exception { PointChange change = calcChange(point(50, 50), hLine(10, 200, 50), hLine(10, 50, 100)); assertPoint(0, 50, change); } @Test public void moveVerticalResizeHorizontal_pointMovesVerticalAndStaysOnLeftEnd() throws Exception { PointChange change = calcChange(point(50, 50), hLine(10, 200, 50), hLine(10, 20, 100)); assertPoint(-30, 50, change); } private void assertPoint(int x, int y, PointChange change) { assertEquals("correct x movement", x, change.getDiffX()); assertEquals("correct y movement", y, change.getDiffY()); } private PointChange calcChange(PointDouble point, StickLine oldLine, int xChange, int yChange) { PointDouble oStart = oldLine.getStart(); PointDouble oEnd = oldLine.getEnd(); return Stickables.calcPointDiffBasedOnStickLineChange(0, point, new StickLineChange(oldLine, line(oStart.getX() + xChange, oStart.getY() + yChange, oEnd.getX() + xChange, oEnd.getY() + yChange))); } private PointChange calcChange(PointDouble point, StickLine oldLine, StickLine newLine) { return Stickables.calcPointDiffBasedOnStickLineChange(0, point, new StickLineChange(oldLine, newLine)); } private static PointDouble point(double x, double y) { return new PointDouble(x, y); } private static StickLine line(double xStart, double yStart, double xEnd, double yEnd) { return new StickLine(point(xStart, yStart), point(xEnd, yEnd)); } private static StickLine hLine(double xStart, double xEnd, double y) { return line(xStart, y, xEnd, y); } private static StickLine vLine(double x, double yStart, double yEnd) { return line(x, yStart, x, yEnd); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/control/0000755000175000017500000000000012533641120023133 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/test/com/baselet/control/SharedUtilsTest.java0000644000175000017500000000132312533641120027064 0ustar benbenpackage com.baselet.control; import static org.junit.Assert.assertEquals; import org.junit.Test; public class SharedUtilsTest { @Test public void testRealignToGridRoundToNearest() { assertEquals(10, SharedUtils.realignToGridRoundToNearest(false, 5.0)); assertEquals(10, SharedUtils.realignToGridRoundToNearest(false, 9.0)); assertEquals(0, SharedUtils.realignToGridRoundToNearest(false, 4.0)); assertEquals(-10, SharedUtils.realignToGridRoundToNearest(false, -5.0)); assertEquals(-10, SharedUtils.realignToGridRoundToNearest(false, -9.0)); assertEquals(0, SharedUtils.realignToGridRoundToNearest(false, -3.0)); assertEquals(0, SharedUtils.realignToGridRoundToNearest(false, 0)); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/.project0000644000175000017500000000060712533641120017751 0ustar benben BaseletElements org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature umlet-2015-06-03_UMLet_v13.3/BaseletElements/.classpath0000644000175000017500000000063412533641120020265 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletElements/.gitignore0000644000175000017500000000000612533641120020263 0ustar benben/bin/ umlet-2015-06-03_UMLet_v13.3/BaseletElements/.settings/0000755000175000017500000000000012533641120020215 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/.settings/org.eclipse.jdt.core.prefs0000644000175000017500000005755712533641120025222 0ustar benbeneclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true org.eclipse.jdt.core.formatter.comment.format_block_comments=true org.eclipse.jdt.core.formatter.comment.format_header=true org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false org.eclipse.jdt.core.formatter.comment.format_line_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert org.eclipse.jdt.core.formatter.comment.line_length=9999 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=false org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=false org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=999 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false org.eclipse.jdt.core.formatter.tabulation.char=tab org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true umlet-2015-06-03_UMLet_v13.3/BaseletElements/.settings/org.eclipse.jdt.ui.prefs0000644000175000017500000001217212533641120024667 0ustar benbencleanup.add_default_serial_version_id=false cleanup.add_generated_serial_version_id=true cleanup.add_missing_annotations=true cleanup.add_missing_deprecated_annotations=true cleanup.add_missing_methods=false cleanup.add_missing_nls_tags=false cleanup.add_missing_override_annotations=true cleanup.add_missing_override_annotations_interface_methods=true cleanup.add_serial_version_id=false cleanup.always_use_blocks=true cleanup.always_use_parentheses_in_expressions=false cleanup.always_use_this_for_non_static_field_access=false cleanup.always_use_this_for_non_static_method_access=false cleanup.convert_to_enhanced_for_loop=true cleanup.correct_indentation=false cleanup.format_source_code=true cleanup.format_source_code_changes_only=false cleanup.make_local_variable_final=true cleanup.make_parameters_final=false cleanup.make_private_fields_final=false cleanup.make_type_abstract_if_missing_method=false cleanup.make_variable_declarations_final=false cleanup.never_use_blocks=false cleanup.never_use_parentheses_in_expressions=true cleanup.organize_imports=true cleanup.qualify_static_field_accesses_with_declaring_class=false cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true cleanup.qualify_static_member_accesses_with_declaring_class=true cleanup.qualify_static_method_accesses_with_declaring_class=false cleanup.remove_private_constructors=true cleanup.remove_trailing_whitespaces=true cleanup.remove_trailing_whitespaces_all=true cleanup.remove_trailing_whitespaces_ignore_empty=false cleanup.remove_unnecessary_casts=true cleanup.remove_unnecessary_nls_tags=true cleanup.remove_unused_imports=false cleanup.remove_unused_local_variables=false cleanup.remove_unused_private_fields=true cleanup.remove_unused_private_members=false cleanup.remove_unused_private_methods=true cleanup.remove_unused_private_types=true cleanup.sort_members=false cleanup.sort_members_all=false cleanup.use_blocks=true cleanup.use_blocks_only_for_return_and_throw=false cleanup.use_parentheses_in_expressions=true cleanup.use_this_for_non_static_field_access=true cleanup.use_this_for_non_static_field_access_only_if_necessary=true cleanup.use_this_for_non_static_method_access=true cleanup.use_this_for_non_static_method_access_only_if_necessary=true cleanup_profile=_Umlet Cleanup cleanup_settings_version=2 eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_Umlet Formatter formatter_settings_version=12 sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true sp_cleanup.add_missing_deprecated_annotations=true sp_cleanup.add_missing_methods=false sp_cleanup.add_missing_nls_tags=false sp_cleanup.add_missing_override_annotations=true sp_cleanup.add_missing_override_annotations_interface_methods=true sp_cleanup.add_serial_version_id=false sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false sp_cleanup.convert_to_enhanced_for_loop=true sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false sp_cleanup.make_variable_declarations_final=true sp_cleanup.never_use_blocks=false sp_cleanup.never_use_parentheses_in_expressions=true sp_cleanup.on_save_use_additional_actions=true sp_cleanup.organize_imports=true sp_cleanup.qualify_static_field_accesses_with_declaring_class=false sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_with_declaring_class=true sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true sp_cleanup.remove_trailing_whitespaces=true sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true sp_cleanup.remove_unnecessary_nls_tags=true sp_cleanup.remove_unused_imports=false sp_cleanup.remove_unused_local_variables=false sp_cleanup.remove_unused_private_fields=true sp_cleanup.remove_unused_private_members=false sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false sp_cleanup.use_blocks=true sp_cleanup.use_blocks_only_for_return_and_throw=false sp_cleanup.use_parentheses_in_expressions=true sp_cleanup.use_this_for_non_static_field_access=true sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=true sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true umlet-2015-06-03_UMLet_v13.3/BaseletElements/.settings/org.eclipse.core.resources.prefs0000644000175000017500000000007112533641120026426 0ustar benbeneclipse.preferences.version=1 encoding/=UTF-8 umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/0000755000175000017500000000000012533641120017066 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/0000755000175000017500000000000012533641120017644 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/0000755000175000017500000000000012533641120021263 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/0000755000175000017500000000000012533641120022714 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/0000755000175000017500000000000012533641120023776 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/FirstRunFacet.java0000644000175000017500000000024412533641120027360 0ustar benbenpackage com.baselet.element.facet; public abstract class FirstRunFacet extends Facet { @Override public boolean handleOnFirstRun() { return true; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/Buffer.java0000644000175000017500000000236412533641120026057 0ustar benbenpackage com.baselet.element.facet; /** * represents the space buffer around the printed PropertiesText * Many Facets set restrictions via the buffer (e.g. a Package element should never print text over the upper left rectangle) * The most important buffer-reader is the TextPrintFacet which uses it to calculate the text position */ public class Buffer { private double top = 0; // the top space where no text should be placed (e.g. the upper left rectangle of the Package element) private double left = 0; private double right = 0; public double getTop() { return top; } public double getLeft() { return left; } public double getRight() { return right; } public void addToLeft(double inc) { left += inc; } public void addToRight(double inc) { right += inc; } /** * sets the required top buffer. it is always the max from this or the previous buffer, because the facets are independent from each other * if one required 20px and the other 10px, in general 20px are required to satisfy the requirements of both facets */ public void setTopMin(double newMin) { top = Math.max(top, newMin); } public void addToLeftAndRight(double inc) { addToLeft(inc); addToRight(inc); } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/FirstRunKeyValueFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/FirstRunKeyValueFacet.jav0000644000175000017500000000026412533641120030667 0ustar benbenpackage com.baselet.element.facet; public abstract class FirstRunKeyValueFacet extends KeyValueFacet { @Override public boolean handleOnFirstRun() { return true; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/0000755000175000017500000000000012533641120025563 5ustar benben././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/StateTypeFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/StateTypeFacet.j0000644000175000017500000000513012533641120030622 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.PointDouble; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; /** * must be in first-run because it manipulates the left buffer which is used by second-run facets * must handle values in parsingFinished when drawer-setup is finished */ public class StateTypeFacet extends FirstRunKeyValueFacet { public static final StateTypeFacet INSTANCE = new StateTypeFacet(); private StateTypeFacet() {} private enum ActionTypeEnum { STATE, SENDER, RECEIVER } @Override public KeyValue getKeyValue() { return new KeyValue("type", new ValueInfo(ActionTypeEnum.STATE, "a default state"), new ValueInfo(ActionTypeEnum.SENDER, "an action which sends a signal"), new ValueInfo(ActionTypeEnum.RECEIVER, "an action which receives a signal")); } @Override public void handleValue(final String value, final PropertiesParserState state) { // only act if parsing is finished to make sure DrawHandler-Setup is finished } private void drawActionState(final DrawHandler drawer, Dimension s) { int radius = Math.min(20, Math.min(s.width, s.height) / 5); drawer.drawRectangleRound(0, 0, s.width, s.height, radius); } private double depth(Dimension s) { return s.width / 5.0; } private PointDouble p(double x, double y) { return new PointDouble(x, y); } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { if (handledLines.isEmpty()) { drawActionState(state.getDrawer(), state.getGridElementSize()); } else if (handledLines.size() == 1) { final PropertiesParserState state1 = state; DrawHandler drawer = state1.getDrawer(); ActionTypeEnum type = ActionTypeEnum.valueOf(extractValue(handledLines.get(0).toUpperCase())); Dimension s = state1.getGridElementSize(); if (type == ActionTypeEnum.STATE) { drawActionState(drawer, s); } else if (type == ActionTypeEnum.SENDER) { drawer.drawLines(Arrays.asList(p(0, 0), p(s.width - depth(s), 0), p(s.width, s.height / 2.0), p(s.width - depth(s), s.height), p(0, s.height), p(0, 0))); } else if (type == ActionTypeEnum.RECEIVER) { state1.getBuffer().addToLeft(depth(s)); drawer.drawLines(Arrays.asList(p(0, 0), p(s.width, 0), p(s.width, s.height), p(0, s.height), p(depth(s), s.height / 2.0), p(0, 0))); } } } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/InnerClassFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/InnerClassFacet.0000644000175000017500000000631712533641120030577 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.Arrays; import java.util.List; import java.util.Stack; import com.baselet.control.basics.XValues; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.AlignVertical; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.facet.Alignment; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.gui.AutocompletionText; public class InnerClassFacet extends Facet { public static final InnerClassFacet INSTANCE = new InnerClassFacet(); private InnerClassFacet() {} private static final int BUFFER_PIXEL_PER_INNER = 5; private static final int H_SPACE = 4; private static final String START = "{innerclass"; private static final String END = "innerclass}"; @Override public boolean checkStart(String line, PropertiesParserState state) { return line.equals(START) || line.equals(END); } @Override public void handleLine(String line, PropertiesParserState state) { Stack innerClassStartPoints = getOrInit(state); DrawHandler drawer = state.getDrawer(); if (line.equals(START)) { ClassSettings settings = new ClassSettings(state.getAlignment().getHorizontal(), state.getAlignment().getVertical(), getDividerPos(drawer, state)); innerClassStartPoints.add(settings); state.getBuffer().addToLeftAndRight(BUFFER_PIXEL_PER_INNER); state.increaseTextPrintPosition(H_SPACE); state.getAlignment().reset(); } else if (line.equals(END)) { ClassSettings previousClassSettings = innerClassStartPoints.pop(); double start = previousClassSettings.start; double height = getDividerPos(drawer, state) - start; XValues xLimit = state.getXLimits(height); ColorOwn oldColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); drawer.drawRectangle(xLimit.getLeft(), start, xLimit.getSpace(), height); drawer.setBackgroundColor(oldColor); state.increaseTextPrintPosition(H_SPACE); state.getBuffer().addToLeftAndRight(-BUFFER_PIXEL_PER_INNER); Alignment alignment = state.getAlignment(); alignment.setHorizontal(false, previousClassSettings.hAlign); alignment.setVertical(false, previousClassSettings.vAlign); } } private double getDividerPos(DrawHandler drawer, PropertiesParserState state) { return state.getTextPrintPosition() - drawer.textHeightMax(); } private Stack getOrInit(PropertiesParserState state) { return state.getOrInitFacetResponse(InnerClassFacet.class, new Stack()); } private static class ClassSettings { private final AlignHorizontal hAlign; private final AlignVertical vAlign; private final double start; public ClassSettings(AlignHorizontal hAlign, AlignVertical vAlign, double startpoint) { super(); this.hAlign = hAlign; this.vAlign = vAlign; start = startpoint; } } @Override public List getAutocompletionStrings() { return Arrays.asList(new AutocompletionText(START, "begin inner class"), new AutocompletionText(END, "end inner class")); } } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/UpperRightSymbolFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/UpperRightSymbol0000644000175000017500000000775712533641120031005 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; /** * must be in first-run because it manipulates the left buffer which is used by second-run facets * must handle values in parsingFinished when drawer-setup is finished */ public class UpperRightSymbolFacet extends FirstRunKeyValueFacet { public static final UpperRightSymbolFacet INSTANCE = new UpperRightSymbolFacet(); private UpperRightSymbolFacet() {} private enum UpperRightSymbolEnum { USECASE, ARTIFACT, COMPONENT } @Override public KeyValue getKeyValue() { return new KeyValue("symbol", new ValueInfo(UpperRightSymbolEnum.USECASE, "draw a use case symbol"), new ValueInfo(UpperRightSymbolEnum.ARTIFACT, "draw an artifact symbol"), new ValueInfo(UpperRightSymbolEnum.COMPONENT, "draw a component symbol")); } private static final int DISTANCE = 5; @Override public void handleValue(String value, PropertiesParserState state) { // only act if parsing is finished to make sure DrawHandler-Setup is finished } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { if (!handledLines.isEmpty()) { DrawHandler drawer = state.getDrawer(); ColorOwn prevBackgroundColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); UpperRightSymbolEnum symbol = UpperRightSymbolEnum.valueOf(extractValue(handledLines.get(0)).toUpperCase()); double eW = state.getGridElementSize().getWidth(); double fs = drawer.getFontSize(); if (symbol == UpperRightSymbolEnum.USECASE) { double cW = fs * 2.5; double cH = fs; drawer.drawEllipse(eW - cW - DISTANCE, DISTANCE, cW, cH); state.getBuffer().setTopMin(DISTANCE); } else if (symbol == UpperRightSymbolEnum.ARTIFACT) { double cW = fs * 1.5; double cH = fs * 1.8; double corner = fs * 0.5; List p = Arrays.asList( new PointDouble(eW - cW - DISTANCE, DISTANCE), new PointDouble(eW - DISTANCE - corner, DISTANCE), new PointDouble(eW - DISTANCE, DISTANCE + corner), new PointDouble(eW - DISTANCE, DISTANCE + cH), new PointDouble(eW - cW - DISTANCE, DISTANCE + cH) ); PointDouble px = new PointDouble(eW - DISTANCE - corner, DISTANCE + corner); drawer.drawLines(p.get(0), p.get(1), p.get(2), p.get(3), p.get(4), p.get(0)); drawer.drawLines(p.get(1), px, p.get(2)); state.getBuffer().setTopMin(DISTANCE + fs * 0.3); } else if (symbol == UpperRightSymbolEnum.COMPONENT) { double partHeight = fs * 0.4; double nonPartHeight = fs * 0.3; double partWidth = partHeight * 2; double cH = partHeight * 2 + nonPartHeight * 3; double cW = cH * 0.8; drawer.drawRectangle(eW - cW - partWidth / 2 - DISTANCE, DISTANCE + nonPartHeight, partWidth, partHeight); // upper small rect drawer.drawRectangle(eW - cW - partWidth / 2 - DISTANCE, DISTANCE + partHeight + nonPartHeight * 2, partWidth, partHeight); // lower small rect drawer.drawLine(eW - cW - DISTANCE, DISTANCE + partHeight + nonPartHeight, eW - cW - DISTANCE, DISTANCE + partHeight + nonPartHeight * 2); // connection between 2 rects drawer.drawLines(Arrays.asList( // draw large rectangle around new PointDouble(eW - cW - DISTANCE, DISTANCE + nonPartHeight), new PointDouble(eW - cW - DISTANCE, DISTANCE), new PointDouble(eW - DISTANCE, DISTANCE), new PointDouble(eW - DISTANCE, DISTANCE + cH), new PointDouble(eW - cW - DISTANCE, DISTANCE + cH), new PointDouble(eW - cW - DISTANCE, DISTANCE + cH - nonPartHeight) )); state.getBuffer().setTopMin(DISTANCE + fs * 0.3); } drawer.setBackgroundColor(prevBackgroundColor); } } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/HierarchyFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/HierarchyFacet.j0000644000175000017500000001654512533641120030632 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.DrawHandler.Layer; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.draw.DrawHelper; import com.baselet.element.facet.Facet; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.gui.AutocompletionText; public class HierarchyFacet extends Facet { private static final double ARROW_LENGTH = 12; private static final double CIRCLE_DIAMETER = 10; private static final String KEY = "type"; private static final class ReferencePoint { PointDouble p; boolean hasSymbol = false; public ReferencePoint(PointDouble p) { super(); this.p = p; } } private static final class Cache { HierarchyType type = HierarchyType.Actor; private int lineNr; private final List points = new ArrayList(); } public static enum HierarchyType { Actor, Package, WorkProcess; } public static final HierarchyFacet INSTANCE = new HierarchyFacet(); @Override public boolean checkStart(String line, PropertiesParserState state) { return true; } @Override public void handleLine(String line, PropertiesParserState state) { if (line.isEmpty()) { return; } Cache cache = state.getOrInitFacetResponse(HierarchyFacet.class, new Cache()); for (HierarchyType type : HierarchyType.values()) { if (line.equals(KEY + KeyValueFacet.SEP + type)) { cache.type = type; return; } } DrawHandler drawer = state.getDrawer(); drawer.setLayer(Layer.Foreground); ColorOwn bgBefore = drawer.getBackgroundColor(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); String lineWithoutTabs = line.replace("\t", ""); int tabCount = line.length() - lineWithoutTabs.length(); int border = 10; PointDouble upperLeftPoint = null; PointDouble lowerRightPoint = null; PointDouble textPos = null; if (cache.type == HierarchyType.Actor) { int actorDimension = 10; int actorHCenter = border + actorDimension + actorDimension * 5 * tabCount; int actorVTop = border + cache.lineNr * actorDimension * 6; DrawHelper.drawActor(drawer, actorHCenter, actorVTop, actorDimension); upperLeftPoint = new PointDouble(actorHCenter, actorVTop + actorDimension * 5.5 + ARROW_LENGTH); lowerRightPoint = new PointDouble(actorHCenter - actorDimension * 2, actorVTop + actorDimension * 2.5); drawLinesAndUpperLeftSymbol(lowerRightPoint, drawer, cache, lineWithoutTabs, tabCount, true); textPos = new PointDouble(actorHCenter + actorDimension * 2, actorVTop + actorDimension * 3); drawer.print(lineWithoutTabs, textPos, AlignHorizontal.LEFT); updateElementSize(state, lineWithoutTabs, lowerRightPoint, textPos, drawer.textWidth(lineWithoutTabs), DrawHelper.headToLegLength(actorDimension)); } else if (cache.type == HierarchyType.Package) { int fullHeight = 20; int fullWidth = 30; double xPos = border + tabCount * fullWidth * 1.4; double yPos = border + cache.lineNr * fullHeight * 1.6; DrawHelper.drawPackage(drawer, xPos, yPos, 5, 10, fullHeight, fullWidth); upperLeftPoint = new PointDouble(xPos + fullWidth * 0.3, yPos + fullHeight + CIRCLE_DIAMETER); lowerRightPoint = new PointDouble(xPos, yPos + fullHeight * 0.5); drawLinesAndUpperLeftSymbol(lowerRightPoint, drawer, cache, lineWithoutTabs, tabCount, false); textPos = new PointDouble(xPos + fullWidth * 1.15, yPos + fullHeight * 0.8); drawer.print(lineWithoutTabs, textPos, AlignHorizontal.LEFT); updateElementSize(state, lineWithoutTabs, lowerRightPoint, textPos, drawer.textWidth(lineWithoutTabs), fullHeight + SharedConstants.DEFAULT_GRID_SIZE); } else if (cache.type == HierarchyType.WorkProcess) { int fullHeight = 40; int fullWidth = 140; double xPos = border + tabCount * fullWidth; double yPos = border + cache.lineNr * fullHeight * 1.2; drawer.drawEllipse(xPos, yPos, fullWidth, fullHeight); upperLeftPoint = new PointDouble(xPos + fullWidth * 0.5, yPos + fullHeight + ARROW_LENGTH); lowerRightPoint = new PointDouble(xPos, yPos + fullHeight * 0.5); drawLinesAndUpperLeftSymbol(lowerRightPoint, drawer, cache, lineWithoutTabs, tabCount, true); textPos = new PointDouble(xPos + fullWidth / 2.0, yPos + fullHeight / 2.0 + drawer.textHeight(lineWithoutTabs) / 2.0); drawer.print(lineWithoutTabs, textPos, AlignHorizontal.CENTER); updateElementSize(state, lineWithoutTabs, lowerRightPoint, textPos, fullWidth / 2, fullHeight); } // store last point as reference if (tabCount == 0) { cache.points.clear(); } // for each tab which is missing in this line compared to the previous one, remove one stored point while (cache.points.size() > tabCount) { cache.points.remove(cache.points.size() - 1); } cache.points.add(new ReferencePoint(upperLeftPoint)); cache.lineNr++; drawer.setLayer(Layer.Background); drawer.setBackgroundColor(bgBefore); } private void updateElementSize(PropertiesParserState state, String lineWithoutTabs, PointDouble lowerRightPoint, PointDouble textPos, double widthAddon, double heightAddon) { state.updateMinimumSize(textPos.x + widthAddon, lowerRightPoint.y + heightAddon); } private static void drawLinesAndUpperLeftSymbol(PointDouble lowerRightPoint, DrawHandler drawer, Cache cache, String lineWithoutTabs, int tabCount, boolean arrow) { if (tabCount != 0) { try { ReferencePoint ref = cache.points.get(tabCount - 1); PointDouble p1 = new PointDouble(lowerRightPoint.x, lowerRightPoint.y); PointDouble p2 = new PointDouble(ref.p.x, lowerRightPoint.y); PointDouble p3 = new PointDouble(ref.p.x, ref.p.y); drawer.drawLines(p1, p2, p3); if (!ref.hasSymbol) { ref.hasSymbol = true; if (arrow) { PointDouble upper = new PointDouble(ref.p.x, ref.p.y - ARROW_LENGTH); PointDouble lowerLeft = new PointDouble(ref.p.x - ARROW_LENGTH / 2, ref.p.y); PointDouble lowerRight = new PointDouble(ref.p.x + ARROW_LENGTH / 2, ref.p.y); drawer.drawLines(upper, lowerLeft, lowerRight, upper); } else { int dist = 2; double circleRadius = CIRCLE_DIAMETER / 2; drawer.drawCircle(ref.p.x, ref.p.y - circleRadius, circleRadius); drawer.drawLine(ref.p.x, ref.p.y - CIRCLE_DIAMETER + dist, ref.p.x, ref.p.y - dist); drawer.drawLine(ref.p.x - circleRadius + dist, ref.p.y - circleRadius, ref.p.x + circleRadius - dist, ref.p.y - circleRadius); } } } catch (IndexOutOfBoundsException e) { throw new RuntimeException("Too many tabs in line nr." + (cache.lineNr + 1) + ": " + lineWithoutTabs); } } } @Override public List getAutocompletionStrings() { return Arrays.asList(new AutocompletionText(KEY + KeyValueFacet.SEP + HierarchyType.Actor, "draws hierarchy of actors"), new AutocompletionText(KEY + KeyValueFacet.SEP + HierarchyType.Package, "draws hierarchy of packages"), new AutocompletionText(KEY + KeyValueFacet.SEP + HierarchyType.WorkProcess, "draws hierarchy of work processes")); } } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/SpecialStateTypeFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/SpecialStateType0000644000175000017500000001122212533641120030727 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.AlignHorizontal; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class SpecialStateTypeFacet extends KeyValueFacet { public static final SpecialStateTypeFacet INSTANCE = new SpecialStateTypeFacet(); private SpecialStateTypeFacet() {} private enum StateTypeEnum { INITIAL, FINAL, FLOW_FINAL, TERMINATION, DECISION, HISTORY_SHALLOW, HISTORY_DEEP } @Override public KeyValue getKeyValue() { return new KeyValue("type", new ValueInfo(StateTypeEnum.INITIAL, "an initial state"), new ValueInfo(StateTypeEnum.FINAL, "a final state for the activity"), new ValueInfo(StateTypeEnum.FLOW_FINAL, "a final state for a flow"), new ValueInfo(StateTypeEnum.HISTORY_SHALLOW, "a shallow history state"), new ValueInfo(StateTypeEnum.HISTORY_DEEP, "a deep history state"), new ValueInfo(StateTypeEnum.TERMINATION, "a termination state"), new ValueInfo(StateTypeEnum.DECISION, "a decision")); } @Override public void handleValue(final String value, final PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); StateTypeEnum type = StateTypeEnum.valueOf(value.toUpperCase()); Dimension s = state.getGridElementSize(); // IMPORTANT NOTE: Make sure the element looks good in Swing and GWT because it's quite complex because of 1px displacements (check in UML State Machine palette) double w = getWidth(s); double h = getHeight(s); if (type == StateTypeEnum.INITIAL) { drawBlackEllipse(drawer, w - 1, h - 1, 1); } else if (type == StateTypeEnum.FINAL) { drawer.drawEllipse(0, 0, w, h); ColorOwn oldFg = drawer.getForegroundColor(); drawer.setForegroundColor(ColorOwn.TRANSPARENT); // don't use foregroundcolor for the inner circle, because otherwise in Swing it would look very ugly double ellipseDistance = Math.max(w - 1, h - 1) / 5.5; drawBlackEllipse(drawer, w - ellipseDistance * 2, h - ellipseDistance * 2, ellipseDistance); drawer.setForegroundColor(oldFg); } else if (type == StateTypeEnum.FLOW_FINAL) { drawer.drawEllipse(0, 0, w, h); double upperY = h / 6; double lowerY = h - upperY; XValues upperXVal = XValues.createForEllipse(upperY, h, w); XValues lowerXVal = XValues.createForEllipse(lowerY, h, w); drawer.drawLine(upperXVal.getLeft(), upperY, lowerXVal.getRight(), lowerY); drawer.drawLine(lowerXVal.getLeft(), lowerY, upperXVal.getRight(), upperY); } else if (type == StateTypeEnum.HISTORY_SHALLOW || type == StateTypeEnum.HISTORY_DEEP) { String text; if (type == StateTypeEnum.HISTORY_SHALLOW) { text = "*H*"; } else { text = "*H**"; } drawer.drawEllipse(0, 0, w, h); double x = (w - drawer.textWidth(text)) / 2; double y = (h + drawer.textHeight(text)) / 2; drawer.print(text, new PointDouble(x, y), AlignHorizontal.LEFT); } else if (type == StateTypeEnum.TERMINATION) { drawer.drawLine(0, 0, w, h); drawer.drawLine(w, 0, 0, h); } else if (type == StateTypeEnum.DECISION) { drawDecision(drawer, w, h); } } private void drawDecision(final DrawHandler drawer, final double w, final double h) { drawer.drawLines(new PointDouble(0.5 + w / 2, 1), new PointDouble(w, 0.5 + h / 2), new PointDouble(0.5 + w / 2, h), new PointDouble(1, 0.5 + h / 2), new PointDouble(0.5 + w / 2, 1)); } private void drawBlackEllipse(final DrawHandler drawer, double width, double height, double xY) { ColorOwn oldBg = drawer.getBackgroundColor(); if (drawer.getBackgroundColor() == ColorOwn.DEFAULT_BACKGROUND) { drawer.setBackgroundColor(ColorOwn.BLACK.transparency(Transparency.FOREGROUND)); } else { drawer.setBackgroundColor(drawer.getBackgroundColor().transparency(Transparency.FOREGROUND)); } drawer.drawEllipse(xY, xY, width, height); drawer.setBackgroundColor(oldBg); } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { if (handledLines.isEmpty()) { // default is decision Dimension s = state.getGridElementSize(); drawDecision(state.getDrawer(), getWidth(s), getHeight(s)); } } private int getHeight(Dimension s) { return s.getHeight() - 1; } private int getWidth(Dimension s) { return s.getWidth() - 1; } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/TemplateClassFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/TemplateClassFac0000644000175000017500000001041312533641120030660 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.Arrays; import java.util.List; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.Style; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.sticking.polygon.PointDoubleStickingPolygonGenerator; import com.baselet.element.sticking.polygon.SimpleStickingPolygonGenerator; /** * must be in first run, because the execution of Class.drawCommonContent() depends on the result of this facet */ public class TemplateClassFacet extends FirstRunKeyValueFacet { public static final TemplateClassFacet INSTANCE = new TemplateClassFacet(); private TemplateClassFacet() {} public static final int UPPER_SPACE = 3; public static final int LOWER_SPACE = 3; public static final int LEFT_SPACE = 12; @Override public KeyValue getKeyValue() { return new KeyValue("template", new ValueInfo("text", "print template rectangle on top right corner")); } @Override public void handleValue(String value, PropertiesParserState state) { // only act after parsing } private static int round(double val) { return SharedUtils.realignToGrid(false, val, true); } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { DrawHandler drawer = state.getDrawer(); int height = state.getGridElementSize().getHeight(); int width = state.getGridElementSize().getWidth(); if (handledLines.isEmpty()) { drawer.drawRectangle(0, 0, width, height); state.setStickingPolygonGenerator(SimpleStickingPolygonGenerator.INSTANCE); } else if (handledLines.size() == 1) { List points = TemplateClassFacet.drawTemplateClass(extractValue(handledLines.get(0)), drawer, state, height, width); state.setStickingPolygonGenerator(new PointDoubleStickingPolygonGenerator(points)); } else { throw new StyleException("Only one class template is allowed"); } } private static List drawTemplateClass(String templateClassText, DrawHandler drawer, PropertiesParserState state, int height, int width) { Rectangle tR = calcTemplateRect(templateClassText, drawer, width); int classTopEnd = round(tR.getHeight() / 2.0); int classWidth = width - round(tR.getWidth() / 2.0); PointDouble start = new PointDouble(0, classTopEnd); List p = Arrays.asList( start, new PointDouble(tR.getX(), classTopEnd), new PointDouble(tR.getX(), 0), new PointDouble(width, 0), new PointDouble(width, tR.getHeight()), new PointDouble(classWidth, tR.getHeight()), new PointDouble(classWidth, height), new PointDouble(0, height), start); // SET BUFFERS FOR REDUCED CLASS BORDER state.getBuffer().setTopMin(tR.getHeight()); state.getBuffer().addToRight(width - classWidth); // DRAW BACKGROUND RECT Style style = drawer.getStyleClone(); drawer.setForegroundColor(ColorOwn.TRANSPARENT); drawer.drawLines(p); drawer.setStyle(style); // reset style to state before manipulations // DRAW RIGHT RECT drawer.setLineType(LineType.DASHED); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); drawer.drawRectangle(tR); drawer.setStyle(style); // reset style to state before manipulations // DRAW PARTIAL CLASS BORDER drawer.drawLines(p.get(1), p.get(0), p.get(7), p.get(6), p.get(5)); // DRAW TEMPLATE TEXT drawer.print(templateClassText, width - drawer.getDistanceBorderToText(), tR.getHeight() - LOWER_SPACE, AlignHorizontal.RIGHT); return p; } private static Rectangle calcTemplateRect(String templateClassText, DrawHandler drawer, int width) { double templateHeight = drawer.textHeightMax() + UPPER_SPACE + LOWER_SPACE; double templateWidth = drawer.textWidth(templateClassText) + LEFT_SPACE; Rectangle tR = new Rectangle(width - templateWidth, 0.0, templateWidth, templateHeight); return tR; } } ././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/SubStateSymbolFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/SubStateSymbolFa0000644000175000017500000000361012533641120030675 0ustar benbenpackage com.baselet.element.facet.specific; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.DrawHandler.Layer; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class SubStateSymbolFacet extends KeyValueFacet { public static final SubStateSymbolFacet INSTANCE = new SubStateSymbolFacet(); private SubStateSymbolFacet() {} private enum SubStateSymbolEnum { SUBSTATE } @Override public KeyValue getKeyValue() { return new KeyValue("symbol", new ValueInfo(SubStateSymbolEnum.SUBSTATE, "draw a substate symbol in the lower right corner")); } private static final int DIST_RIGHT = 15; private static final int DIST_BOTTOM = 5; @Override public void handleValue(String value, PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); drawer.setLayer(Layer.Foreground); // should be always on top of background ColorOwn prevBackgroundColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); SubStateSymbolEnum symbol = SubStateSymbolEnum.valueOf(value.toUpperCase()); final double w = state.getGridElementSize().getWidth(); final double h = state.getGridElementSize().getHeight(); if (symbol == SubStateSymbolEnum.SUBSTATE) { double cW = drawer.getFontSize() * 1.6; double cH = cW * 0.4; double cR = cW * 0.15; double connectorW = cH; drawer.drawRectangleRound(w - DIST_RIGHT - cW, h - DIST_BOTTOM - cH, cW, cH, cR); drawer.drawRectangleRound(w - DIST_RIGHT - cW - cW - connectorW, h - DIST_BOTTOM - cH, cW, cH, cR); drawer.drawLine(w - DIST_RIGHT - cW - connectorW, h - DIST_BOTTOM - cH / 2, w - DIST_RIGHT - cW, h - DIST_BOTTOM - cH / 2); drawer.setLayer(Layer.Background); drawer.setBackgroundColor(prevBackgroundColor); } } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/ActiveClassFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/specific/ActiveClassFacet0000644000175000017500000000362612533641120030661 0ustar benbenpackage com.baselet.element.facet.specific; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.control.enums.Priority; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; /** * must be in first-run because it manipulates the left buffer which is used by second-run facets * must handle values in parsingFinished when drawer-setup is finished */ public class ActiveClassFacet extends FirstRunKeyValueFacet { public static final ActiveClassFacet INSTANCE = new ActiveClassFacet(); private ActiveClassFacet() {} private static enum ClassTypeEnum { ACTCLASS } @Override public KeyValue getKeyValue() { return new KeyValue("type", new ValueInfo(ClassTypeEnum.ACTCLASS, "make class active (double left/right border)")); } private static final int SPACING = 6; @Override public void handleValue(String value, PropertiesParserState state) { // only act if parsing is finished to make sure DrawHandler-Setup is finished } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { if (!handledLines.isEmpty()) { ClassTypeEnum.valueOf(extractValue(handledLines.get(0)).toUpperCase()); // parse the value to make sure only valid types are accepted state.getBuffer().addToLeftAndRight(SPACING); XValues xLimits = state.getXLimits(state.getTextPrintPosition()); DrawHandler drawer = state.getDrawer(); drawer.drawLine(xLimits.getLeft(), state.getBuffer().getTop(), xLimits.getLeft(), state.getGridElementSize().getHeight()); drawer.drawLine(xLimits.getRight(), state.getBuffer().getTop(), xLimits.getRight(), state.getGridElementSize().getHeight()); } } @Override public Priority getPriority() { return Priority.LOW; // must be after template class to work } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/Settings.java0000644000175000017500000001272212533641120026445 0ustar benbenpackage com.baselet.element.facet; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.AlignVertical; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.common.BackgroundColorFacet; import com.baselet.element.facet.common.ElementStyleFacet; import com.baselet.element.facet.common.FontSizeFacet; import com.baselet.element.facet.common.ForegroundColorFacet; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.facet.common.HorizontalAlignFacet; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.facet.common.LineTypeFacet; import com.baselet.element.facet.common.LineWidthFacet; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.facet.common.TextPrintFacet; import com.baselet.element.facet.common.TransparencyFacet; import com.baselet.element.facet.common.VerticalAlignFacet; import com.baselet.element.facet.specific.HierarchyFacet; import com.baselet.element.relation.facet.LineDescriptionFacet; import com.baselet.element.relation.facet.LineDescriptionPositionFacet; import com.baselet.element.relation.facet.RelationLineTypeFacet; /** * The basic settings of any NewGridElement. * They represent the default values for many important Facets (valign, halign, style) and defines the facets which should be applied to this element * It also specifies if the default text printing should be enabled for this element (e.g. Relation has its own text printing logic) */ public abstract class Settings { // the following lists are default facet configurations. they are declared here as a simple overview and for easy reuse private static final List BASE = listOf(BackgroundColorFacet.INSTANCE, TransparencyFacet.INSTANCE, ForegroundColorFacet.INSTANCE, LayerFacet.INSTANCE, LineWidthFacet.INSTANCE, GroupFacet.INSTANCE); private static final List BASE_WITH_LINETYPE = listOf(BASE, LineTypeFacet.INSTANCE); private static final List BASE_EXTENDED = listOf(BASE_WITH_LINETYPE, TextPrintFacet.INSTANCE, FontSizeFacet.INSTANCE); protected static final List RELATION = listOf(BASE, FontSizeFacet.INSTANCE, RelationLineTypeFacet.INSTANCE, LineDescriptionFacet.INSTANCE, LineDescriptionPositionFacet.INSTANCE_MESSAGE_START, LineDescriptionPositionFacet.INSTANCE_MESSAGE_END, LineDescriptionPositionFacet.INSTANCE_ROLE_START, LineDescriptionPositionFacet.INSTANCE_ROLE_END); protected static final List MANUALRESIZE = listOf(BASE_EXTENDED, VerticalAlignFacet.INSTANCE, HorizontalAlignFacet.INSTANCE, ElementStyleFacet.INSTANCE); protected static final List NOTEXT = BASE_WITH_LINETYPE; protected static final List AUTORESIZE = listOf(BASE_EXTENDED, SeparatorLineFacet.INSTANCE); protected static final List HIERARCHY = listOf(BASE_WITH_LINETYPE, FontSizeFacet.INSTANCE, ElementStyleFacet.INSTANCE_AUTORESIZEONLY, HierarchyFacet.INSTANCE); protected static List listOf(Facet... f) { List facetList = new ArrayList(); facetList.addAll(Arrays.asList(f)); return facetList; } protected static List listOf(List list, Facet... f) { List facetList = new ArrayList(list); facetList.addAll(Arrays.asList(f)); return facetList; } /** * calculates the left and right x value for a certain y value */ public XValues getXValues(double y, int height, int width) { return new XValues(0, width); // default is rectangle form } public AlignVertical getVAlign() { return AlignVertical.TOP; } public AlignHorizontal getHAlign() { return AlignHorizontal.CENTER; } public abstract ElementStyle getElementStyle(); /** * facets are checked and applied during text parsing. * e.g. if a line matches "--" and the facet SeparatorLine is setup for the current element, * a separator line will be drawn instead of printing the text. * * First-run facets are parsed before any other ones, because they influence the whole diagram, even if they are located at the bottom * e.g. style=wordwrap may be located at the bottom but has an influence on every printed line */ protected abstract List createFacets(); private List firstRunFacets; private List secondRunFacets; private void initFacets() { if (firstRunFacets == null) { firstRunFacets = new ArrayList(); secondRunFacets = new ArrayList(); addAll(createFacets()); sortListByPriority(firstRunFacets); sortListByPriority(secondRunFacets); } } private void addAll(List facets) { for (Facet f : facets) { if (f.handleOnFirstRun()) { secondRunFacets.add(f); } else { firstRunFacets.add(f); } } } /** * makes sure that higher priorities are first in the list and therefore are handled first */ private void sortListByPriority(List facets) { Collections.sort(facets, new Comparator() { @Override public int compare(Facet o1, Facet o2) { return o1.getPriority().compareTo(o2.getPriority()); } }); } public final List getFacetsForSecondRun() { initFacets(); return firstRunFacets; } public final List getFacetsForFirstRun() { initFacets(); return secondRunFacets; } }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/0000755000175000017500000000000012533641120025266 5ustar benben././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/LineWidthFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/LineWidthFacet.jav0000644000175000017500000000130112533641120030615 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.constants.FacetConstants; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class LineWidthFacet extends FirstRunKeyValueFacet { public static final LineWidthFacet INSTANCE = new LineWidthFacet(); private LineWidthFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("lw", false, FacetConstants.LINE_WIDTH_DEFAULT + "", "linewidth as decimal number (1.5, 2, ...)"); } @Override public void handleValue(String value, PropertiesParserState state) { state.getDrawer().setLineWidth(Float.valueOf(value)); } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/ElementStyleFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/ElementStyleFacet.0000644000175000017500000000236012533641120030645 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class ElementStyleFacet extends FirstRunKeyValueFacet { private static final ValueInfo NORESIZE_VALUE = new ValueInfo(ElementStyle.NORESIZE, "disable manual resizing"); private static final ValueInfo WORDWRAP_VALUE = new ValueInfo(ElementStyle.WORDWRAP, "wrap lines at the end of the line"); private static final ValueInfo AUTORESIZE_VALUE = new ValueInfo(ElementStyle.AUTORESIZE, "resizes element as text grows"); public static final ElementStyleFacet INSTANCE = new ElementStyleFacet(AUTORESIZE_VALUE, WORDWRAP_VALUE, NORESIZE_VALUE); public static final ElementStyleFacet INSTANCE_AUTORESIZEONLY = new ElementStyleFacet(AUTORESIZE_VALUE); private final ValueInfo[] valueInfo; private ElementStyleFacet(ValueInfo... valueInfo) { this.valueInfo = valueInfo; } @Override public KeyValue getKeyValue() { return new KeyValue("style", valueInfo); } @Override public void handleValue(String value, PropertiesParserState state) { state.setElementStyle(ElementStyle.valueOf(value.toUpperCase())); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/LineTypeFacet.java0000644000175000017500000000221712533641120030627 0ustar benbenpackage com.baselet.element.facet.common; import java.util.Arrays; import java.util.List; import com.baselet.control.enums.LineType; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class LineTypeFacet extends FirstRunKeyValueFacet { public static final LineTypeFacet INSTANCE = new LineTypeFacet(); private LineTypeFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("lt", new ValueInfo(LineType.SOLID.getValue(), "solid lines"), new ValueInfo(LineType.DASHED.getValue(), "dashed lines"), new ValueInfo(LineType.DOTTED.getValue(), "dotted lines")); } private static final List supportedTypes = Arrays.asList(LineType.SOLID, LineType.DASHED, LineType.DOTTED); @Override public void handleValue(String value, PropertiesParserState state) { LineType lt = null; for (LineType s : supportedTypes) { if (s.getValue().equals(value)) { lt = s; } } if (lt == null) { throw new RuntimeException(); // will be translated to usage message } state.getDrawer().setLineType(lt); } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TextPrintFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TextPrintFacet.jav0000644000175000017500000001536312533641120030704 0ustar benbenpackage com.baselet.element.facet.common; import java.util.Collections; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.AlignVertical; import com.baselet.control.enums.ElementStyle; import com.baselet.control.enums.Priority; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.DrawHandler.Layer; import com.baselet.diagram.draw.TextSplitter; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.gui.AutocompletionText; public class TextPrintFacet extends Facet { public static final TextPrintFacet INSTANCE = new TextPrintFacet(); private TextPrintFacet() {} @Override public boolean checkStart(String line, PropertiesParserState state) { return !line.startsWith("//"); // comments start with // and are not printed } @Override public void handleLine(String line, PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); drawer.setLayer(Layer.Foreground); // should be always on top of background setupAtFirstLine(line, drawer, state); if (state.getElementStyle() == ElementStyle.WORDWRAP && !line.trim().isEmpty()) { // empty lines are skipped (otherwise they would get lost) printLineWithWordWrap(line, drawer, state); } else { printLine(line, drawer, state); } drawer.setLayer(Layer.Background); } private static void printLineWithWordWrap(String line, DrawHandler drawer, PropertiesParserState state) { String wrappedLine; while (state.getTextPrintPosition() < state.getGridElementSize().height && !line.trim().isEmpty()) { double spaceForText = state.getXLimitsForArea(state.getTextPrintPosition(), drawer.textHeightMax(), false).getSpace() - drawer.getDistanceBorderToText() * 2; wrappedLine = TextSplitter.splitString(line, spaceForText, drawer); printLine(wrappedLine, drawer, state); line = line.substring(wrappedLine.length()).trim(); } } private static void printLine(String line, DrawHandler drawer, PropertiesParserState state) { XValues xLimitsForText = state.getXLimitsForArea(state.getTextPrintPosition(), drawer.textHeightMax(), false); Double spaceNotUsedForText = state.getGridElementSize().width - xLimitsForText.getSpace(); if (!spaceNotUsedForText.equals(Double.NaN)) { // NaN is possible if xlimits calculation contains e.g. a division by zero state.updateMinimumWidth(spaceNotUsedForText + drawer.textWidth(line)); } AlignHorizontal hAlign = state.getAlignment().getHorizontal(); drawer.print(line, calcHorizontalTextBoundaries(xLimitsForText, drawer.getDistanceBorderToText(), hAlign), state.getTextPrintPosition(), hAlign); state.increaseTextPrintPosition(drawer.textHeightMaxWithSpace()); } /** * before the first line is printed, some space-setup is necessary to make sure the text position is correct */ private static void setupAtFirstLine(String line, DrawHandler drawer, PropertiesParserState state) { boolean isFirstPrintedLine = state.getFacetResponse(TextPrintFacet.class, true); if (isFirstPrintedLine) { state.getBuffer().setTopMin(calcStartPointFromVAlign(drawer, state)); state.getBuffer().setTopMin(calcTopDisplacementToFitLine(line, state, drawer)); state.setFacetResponse(TextPrintFacet.class, false); } } private static double calcStartPointFromVAlign(DrawHandler drawer, PropertiesParserState state) { double returnVal = drawer.textHeightMax(); // print method is located at the bottom of the text therefore add text height (important for UseCase etc where text must not reach out of the border) if (state.getAlignment().getVertical() == AlignVertical.TOP) { returnVal += drawer.getDistanceBorderToText() + state.getBuffer().getTop(); } else if (state.getAlignment().getVertical() == AlignVertical.CENTER) { returnVal += (state.getGridElementSize().height - state.getTotalTextBlockHeight()) / 2 + state.getBuffer().getTop() / 2; } else /* if (state.getvAlign() == AlignVertical.BOTTOM) */{ returnVal += state.getGridElementSize().height - state.getTotalTextBlockHeight() - drawer.textHeightMax() / 4; // 1/4 of textheight is a good value for large fontsizes and "deep" characters like "y" } return returnVal; } /** * Calculates the necessary y-pos space to make the first line fit the xLimits of the element * Currently only used by UseCase element to make sure the first line is moved down as long as it doesn't fit into the available space */ private static double calcTopDisplacementToFitLine(String firstLine, PropertiesParserState state, DrawHandler drawer) { double displacement = state.getTextPrintPosition(); boolean wordwrap = state.getElementStyle() == ElementStyle.WORDWRAP; if (!wordwrap) { // in case of wordwrap or no text, there is no top displacement int BUFFER = 2; // a small buffer between text and outer border double textHeight = drawer.textHeightMax(); double addedSpacePerIteration = textHeight / 2; double availableWidthSpace = state.getXLimitsForArea(displacement, textHeight, true).getSpace() - BUFFER; double accumulator = displacement; int maxLoops = 1000; while (accumulator < state.getGridElementSize().height && !TextSplitter.checkifStringFits(firstLine, availableWidthSpace, drawer)) { if (maxLoops-- < 0) { throw new RuntimeException("Endless loop during calculation of top displacement"); } accumulator += addedSpacePerIteration; double previousWidthSpace = availableWidthSpace; availableWidthSpace = state.getXLimitsForArea(accumulator, textHeight, true).getSpace() - BUFFER; // only set displacement if the last iteration resulted in a space gain (eg: for UseCase until the middle, for Class: stays on top because on a rectangle there is never a width-space gain) if (availableWidthSpace > previousWidthSpace) { displacement = accumulator; } } } return displacement; } private static double calcHorizontalTextBoundaries(XValues xLimitsForText, double distanceBorderToText, AlignHorizontal hAlign) { double x; if (hAlign == AlignHorizontal.LEFT) { x = xLimitsForText.getLeft() + distanceBorderToText; } else if (hAlign == AlignHorizontal.CENTER) { x = xLimitsForText.getSpace() / 2.0 + xLimitsForText.getLeft(); } else /* if (state.gethAlign() == AlignHorizontal.RIGHT) */{ x = xLimitsForText.getRight() - distanceBorderToText; } return x; } @Override public List getAutocompletionStrings() { return Collections.emptyList(); // no autocompletion text for this facet } @Override public Priority getPriority() { return Priority.LOWEST; // only text not used by other facets should be printed } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TransparencyFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TransparencyFacet.0000644000175000017500000000227612533641120030712 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class TransparencyFacet extends FirstRunKeyValueFacet { public static final TransparencyFacet INSTANCE = new TransparencyFacet(); private TransparencyFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("transparency", false, "0", "background color transparency in percent"); } @Override public void handleValue(String value, PropertiesParserState state) { try { int valInt = Integer.parseInt(value); if (valInt < 0 || valInt > 100) { throw new NumberFormatException(); } double colorTransparencyValue = 255 - valInt * 2.55; // ColorOwn has 0 for full transparency and 255 for no transparency ColorOwn bgColor = state.getDrawer().getBackgroundColor(); state.getDrawer().setBackgroundColor(bgColor.transparency((int) colorTransparencyValue)); } catch (NumberFormatException e) { throw new StyleException("The value must be between 0 and 100"); } } }././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/VerticalAlignFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/VerticalAlignFacet0000644000175000017500000000153612533641120030705 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.enums.AlignVertical; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class VerticalAlignFacet extends FirstRunKeyValueFacet { public static final VerticalAlignFacet INSTANCE = new VerticalAlignFacet(); private VerticalAlignFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("valign", new ValueInfo(AlignVertical.TOP, "vertical text alignment"), new ValueInfo(AlignVertical.CENTER, "vertical text alignment"), new ValueInfo(AlignVertical.BOTTOM, "vertical text alignment")); } @Override public void handleValue(String value, PropertiesParserState state) { state.getAlignment().setVertical(true, AlignVertical.valueOf(value.toUpperCase())); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/GroupFacet.java0000644000175000017500000000150712533641120030173 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class GroupFacet extends FirstRunKeyValueFacet { public static final GroupFacet INSTANCE = new GroupFacet(); private GroupFacet() {} public static final String KEY = "group"; @Override public KeyValue getKeyValue() { return new KeyValue(KEY, false, "1", "grouped elements are selected at once"); } @Override public void handleValue(String value, PropertiesParserState state) { try { state.setFacetResponse(GroupFacet.class, Integer.valueOf(value)); } catch (NumberFormatException e) { throw new StyleException("value must be a positive or negative integer"); } } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/ForegroundColorFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/ForegroundColorFac0000644000175000017500000000137212533641120030737 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.constants.FacetConstants; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class ForegroundColorFacet extends FirstRunKeyValueFacet { public static final ForegroundColorFacet INSTANCE = new ForegroundColorFacet(); private ForegroundColorFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue(FacetConstants.FOREGROUND_COLOR_KEY, false, "red", "foreground " + ColorOwn.EXAMPLE_TEXT); } @Override public void handleValue(String value, PropertiesParserState state) { state.getDrawer().setForegroundColor(value); } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/BackgroundColorFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/BackgroundColorFac0000644000175000017500000000137212533641120030704 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.constants.FacetConstants; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class BackgroundColorFacet extends FirstRunKeyValueFacet { public static final BackgroundColorFacet INSTANCE = new BackgroundColorFacet(); private BackgroundColorFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue(FacetConstants.BACKGROUND_COLOR_KEY, false, "red", "background " + ColorOwn.EXAMPLE_TEXT); } @Override public void handleValue(String value, PropertiesParserState state) { state.getDrawer().setBackgroundColor(value); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/FontSizeFacet.java0000644000175000017500000000143612533641120030641 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class FontSizeFacet extends FirstRunKeyValueFacet { public static final FontSizeFacet INSTANCE = new FontSizeFacet(); private FontSizeFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("fontsize", false, "12", "font size as decimal number (12.5, 10.3,...)"); } @Override public void handleValue(String value, PropertiesParserState state) { try { state.getDrawer().setFontSize(Double.valueOf(value)); } catch (NumberFormatException e) { throw new StyleException("value must be a decimal number"); } } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/LayerFacet.java0000644000175000017500000000174612533641120030160 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class LayerFacet extends FirstRunKeyValueFacet { public static final LayerFacet INSTANCE = new LayerFacet(); private LayerFacet() {} public static final String KEY = "layer"; public static final Integer DEFAULT_VALUE = 0; public static final Integer DEFAULT_VALUE_RELATION = 1; @Override public KeyValue getKeyValue() { return new KeyValue(KEY, false, DEFAULT_VALUE.toString(), "higher layers are shown on top of lowers. (-5, 0(=default), 3,...)"); } @Override public void handleValue(String value, PropertiesParserState state) { try { state.setFacetResponse(LayerFacet.class, Integer.valueOf(value)); } catch (NumberFormatException e) { throw new StyleException("value must be a positive or negative integer"); } } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/SeparatorLineFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/SeparatorLineFacet0000644000175000017500000000262312533641120030727 0ustar benbenpackage com.baselet.element.facet.common; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.DrawHandler.Layer; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.gui.AutocompletionText; public class SeparatorLineFacet extends Facet { public static final SeparatorLineFacet INSTANCE = new SeparatorLineFacet(); protected SeparatorLineFacet() {} public static final String KEY = "--"; private static final double Y_SPACE = 5; @Override public void handleLine(String line, PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); drawer.setLayer(Layer.Foreground); // should be always on top of background double linePos = state.getTextPrintPosition() - drawer.textHeightMax() + Y_SPACE / 2; XValues xPos = state.getXLimits(linePos); drawer.drawLine(xPos.getLeft() + 0.5, linePos, xPos.getRight() - 1, linePos); state.increaseTextPrintPosition(Y_SPACE); drawer.setLayer(Layer.Background); } @Override public boolean checkStart(String line, PropertiesParserState state) { return line.equals(KEY); } @Override public List getAutocompletionStrings() { return Arrays.asList(new AutocompletionText(KEY, "draw horizontal line")); } } ././@LongLink0000644000000000000000000000017200000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/SeparatorLineWithHalignChangeFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/SeparatorLineWithH0000644000175000017500000000111712533641120030725 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.enums.AlignHorizontal; import com.baselet.element.facet.PropertiesParserState; public class SeparatorLineWithHalignChangeFacet extends SeparatorLineFacet { public static final SeparatorLineWithHalignChangeFacet INSTANCE = new SeparatorLineWithHalignChangeFacet(); private SeparatorLineWithHalignChangeFacet() {} @Override public void handleLine(String line, PropertiesParserState state) { state.getAlignment().setHorizontal(false, AlignHorizontal.LEFT); super.handleLine(line, state); } } ././@LongLink0000644000000000000000000000017600000000000011607 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TextBeforeFirstSeparatorCollectorFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/TextBeforeFirstSep0000644000175000017500000000370612533641120030746 0ustar benbenpackage com.baselet.element.facet.common; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.enums.Priority; import com.baselet.element.facet.FirstRunFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.gui.AutocompletionText; /** * the collector is the last first-run-facet which should be applied (therefore LOW prio) * it must be in first-run to be applied before the drawCommonContent of the GridElement but after any other first-run-facet */ public class TextBeforeFirstSeparatorCollectorFacet extends FirstRunFacet { public static final TextBeforeFirstSeparatorCollectorFacet INSTANCE = new TextBeforeFirstSeparatorCollectorFacet(); protected TextBeforeFirstSeparatorCollectorFacet() {} public static class TextBeforeFirstSeparatorCollectorFacetResponse { private boolean firstSepFound = false; private final List lines = new ArrayList(); public List getLines() { return lines; } } @Override public boolean checkStart(String line, PropertiesParserState state) { return !getOrInit(state).firstSepFound; } @Override public void handleLine(String line, PropertiesParserState state) { if (line.equals(SeparatorLineFacet.KEY)) { getOrInit(state).firstSepFound = true; return; } else { getOrInit(state).getLines().add(line); } } @Override public List getAutocompletionStrings() { return Arrays.asList(new AutocompletionText(SeparatorLineFacet.KEY, "ends package title part")); } @Override public Priority getPriority() { return Priority.LOW; // only collect which is not used by any other facet } private TextBeforeFirstSeparatorCollectorFacetResponse getOrInit(PropertiesParserState state) { return state.getOrInitFacetResponse(TextBeforeFirstSeparatorCollectorFacet.class, new TextBeforeFirstSeparatorCollectorFacetResponse()); } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/HorizontalAlignFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/common/HorizontalAlignFac0000644000175000017500000000157012533641120030732 0ustar benbenpackage com.baselet.element.facet.common; import com.baselet.control.enums.AlignHorizontal; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; public class HorizontalAlignFacet extends FirstRunKeyValueFacet { public static final HorizontalAlignFacet INSTANCE = new HorizontalAlignFacet(); private HorizontalAlignFacet() {} @Override public KeyValue getKeyValue() { return new KeyValue("halign", new ValueInfo(AlignHorizontal.LEFT, "horizontal text alignment"), new ValueInfo(AlignHorizontal.CENTER, "horizontal text alignment"), new ValueInfo(AlignHorizontal.RIGHT, "horizontal text alignment")); } @Override public void handleValue(String value, PropertiesParserState state) { state.getAlignment().setHorizontal(true, AlignHorizontal.valueOf(value.toUpperCase())); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/Facet.java0000644000175000017500000000534612533641120025673 0ustar benbenpackage com.baselet.element.facet; import java.util.List; import org.apache.log4j.Logger; import com.baselet.control.enums.Priority; import com.baselet.gui.AutocompletionText; /** * A Facet is a simple handler method which acts on certain lines and does a specific job if it should act. * It is important that Facets are ALWAYS STATELESS. * If any State is required, it should be stored using the {@link PropertiesParserState#getOrInitFacetResponse(Class, Object)} method */ public abstract class Facet { protected Logger log = Logger.getLogger(Facet.class); /** * @param line the current line which is parsed * @param state the current state of the parser * @return true if the handleLine() method of this facet should be applied */ public abstract boolean checkStart(String line, PropertiesParserState state); /** * This method is invoked at the time when a specific line is parsed * @param line the current line which is parsed * @param state the current state of the parser */ public abstract void handleLine(String line, PropertiesParserState state); /** * @return a list of objects where each one represents one line for autocompletion */ public abstract List getAutocompletionStrings(); /** * This method is called once for every Facet AFTER all lines of text has been parsed * E.g. useful for facets which collect information with every line but need complete knowledge before they can do something with it * * @param state the current state of the parser * @param handledLines the list of lines this facet has been applied to (in the order of the handleLine calls) */ public void parsingFinished(PropertiesParserState state, List handledLines) { // default is no action } /** * facets with higher priority will be applied before facets with lower priority: * The order is: For all lines * 1. Check all First-Run Facets from HIGHEST ... LOWEST * 2. Check all Second-Run Facets from HIGHEST ... LOWEST */ public Priority getPriority() { return Priority.DEFAULT; } /** * The parser runs twice. Facets where this method returns true, are part of the first run, other facets are part of the second run * * Typically facets of the first run will influence the whole diagram, even if they are located at the bottom. * e.g. bg=red must be known before drawing the common content of an element; style=autoresize must be known as soon as possible to make the size-calculations * * Facets of the second run have less side effects (e.g. printText just prints the current line, -- transforms to a horizontal line at the current print-position) */ public boolean handleOnFirstRun() { return false; } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/PropertiesParserState.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/PropertiesParserState.jav0000644000175000017500000001135012533641120031012 0ustar benbenpackage com.baselet.element.facet; import java.util.HashMap; import java.util.Map; import com.baselet.control.basics.XValues; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.enums.ElementStyle; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.sticking.polygon.SimpleStickingPolygonGenerator; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; /** * The PropertiesParserState contains the mutable state of the parser which changes constantly while parsing * the properties printing related facets have explicit fields (for better usabilty), for any other Facet, the generic facetResponse map should be used for communication between facets and/or the gridelement * */ public class PropertiesParserState { private final Settings settings; private final DrawHandler drawer; private Alignment alignment; private double textPrintPosition; // the current y position for drawing text, separator-lines and other properties-text-related stuff private double minimumWidth; private Buffer buffer; private Dimension gridElementSize; private ElementStyle elementStyle; private StickingPolygonGenerator stickingPolygonGenerator = SimpleStickingPolygonGenerator.INSTANCE; private double totalTextBlockHeight; private final Map, Object> facetResponse = new HashMap, Object>(); public PropertiesParserState(Settings settings, DrawHandler drawer) { this.settings = settings; this.drawer = drawer; } public void resetValues(Dimension gridElementSize, double totalTextBlockHeight, boolean enableDrawing) { alignment = new Alignment(settings); textPrintPosition = 0; minimumWidth = 0; buffer = new Buffer(); this.gridElementSize = gridElementSize; elementStyle = settings.getElementStyle(); stickingPolygonGenerator = SimpleStickingPolygonGenerator.INSTANCE; this.totalTextBlockHeight = totalTextBlockHeight; facetResponse.clear(); drawer.setEnableDrawing(enableDrawing); } public Alignment getAlignment() { return alignment; } /** * returns the current text print position including the top buffer */ public double getTextPrintPosition() { return textPrintPosition + buffer.getTop(); } /** * use whenever the text print position should be increased (e.g. if -- draws a horizontal line, some vertical space should be added, or everytime TextPrintFacet prints a line) */ public void increaseTextPrintPosition(double inc) { textPrintPosition += inc; } public Buffer getBuffer() { return buffer; } public Dimension getGridElementSize() { return gridElementSize; } public XValues getXLimits(double linePos) { XValues xLimits = settings.getXValues(linePos, getGridElementSize().height, getGridElementSize().width); xLimits.addLeft(buffer.getLeft()); xLimits.subRight(buffer.getRight()); return xLimits; } public XValues getXLimitsForArea(double bottomYPos, double areaHeight, boolean nanPriority) { XValues xLimitsTop = getXLimits(bottomYPos - areaHeight); XValues xLimitsBottom = getXLimits(bottomYPos); XValues xLimits = xLimitsTop.intersect(xLimitsBottom, nanPriority); return xLimits; } public void updateMinimumWidth(double width) { minimumWidth = Math.max(minimumWidth, width); } public void updateMinimumSize(double width, double height) { updateMinimumWidth(width); getBuffer().setTopMin(height); } public double getCalculatedElementWidth() { return minimumWidth; } public ElementStyle getElementStyle() { return elementStyle; } public void setElementStyle(ElementStyle elementStyle) { this.elementStyle = elementStyle; } public Settings getSettings() { return settings; } public DrawHandler getDrawer() { return drawer; } @SuppressWarnings("unchecked") public T getFacetResponse(Class facetClass, T defaultValue) { T mapValue = (T) facetResponse.get(facetClass); if (mapValue == null) { return defaultValue; } return mapValue; } public T getOrInitFacetResponse(Class facetClass, T defaultValue) { T mapValue = getFacetResponse(facetClass, defaultValue); setFacetResponse(facetClass, mapValue); return mapValue; } public void setFacetResponse(Class facetClass, Object value) { facetResponse.put(facetClass, value); } public StickingPolygonGenerator getStickingPolygonGenerator() { return stickingPolygonGenerator; } public void setStickingPolygonGenerator(StickingPolygonGenerator stickingPolygonGenerator) { this.stickingPolygonGenerator = stickingPolygonGenerator; } public double getTotalTextBlockHeight() { return totalTextBlockHeight; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/KeyValueFacet.java0000644000175000017500000000665412533641120027344 0ustar benbenpackage com.baselet.element.facet; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.enums.FormatLabels; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.gui.AutocompletionText; public abstract class KeyValueFacet extends Facet { public static class KeyValue { private final String key; private final boolean allValuesListed; private final List valueInfos; public KeyValue(String key, boolean allValuesListed, String value, String info) { super(); this.key = key.toLowerCase(); this.allValuesListed = allValuesListed; valueInfos = Arrays.asList(new ValueInfo(value, info)); } public KeyValue(String key, ValueInfo... valueInfos) { super(); this.key = key; allValuesListed = true; this.valueInfos = Arrays.asList(valueInfos); } public String getKey() { return key; } public List getValueInfos() { return valueInfos; } public String getValueString() { StringBuilder sb = new StringBuilder(); if (allValuesListed) { sb.append("Valid are: "); for (ValueInfo vi : valueInfos) { sb.append(vi.value.toString().toLowerCase()).append(','); } sb.deleteCharAt(sb.length() - 1); } else { for (ValueInfo vi : valueInfos) { sb.append(vi.info); } } return sb.toString(); } } public static class ValueInfo { private final Object value; private final String info; private final String base64Img; public ValueInfo(Object value, String info) { this(value, info, null); } public ValueInfo(Object value, String info, String base64Img) { super(); this.value = value; this.info = info; this.base64Img = base64Img; } public Object getValue() { return value; } private String getInfo() { return info; } private String getBase64Img() { return base64Img; } } public static final String SEP = "="; public abstract KeyValue getKeyValue(); public abstract void handleValue(String value, PropertiesParserState state); @Override public boolean checkStart(String line, PropertiesParserState state) { return line.startsWith(getKeyWithSep()); } @Override public void handleLine(String line, PropertiesParserState state) { String value = extractValue(line); try { handleValue(value, state); } catch (Exception e) { log.debug("KeyValue Error", e); String errorMessage = getKeyValue().getValueString(); if (e instanceof StyleException) { // self defined exceptions overwrite the default message errorMessage = e.getMessage(); } throw new RuntimeException(FormatLabels.BOLD.getValue() + "Invalid value:" + FormatLabels.BOLD.getValue() + "\n" + getKeyWithSep() + value + "\n" + errorMessage); } } protected String extractValue(String line) { return line.substring(getKeyWithSep().length()); } @Override public List getAutocompletionStrings() { List returnList = new ArrayList(); for (ValueInfo valueInfo : getKeyValue().getValueInfos()) { returnList.add(new AutocompletionText(getKeyWithSep() + valueInfo.getValue().toString().toLowerCase(), valueInfo.getInfo(), valueInfo.getBase64Img())); } return returnList; } public String getKeyWithSep() { return getKeyValue().getKey() + KeyValueFacet.SEP; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/facet/Alignment.java0000644000175000017500000000307112533641120026560 0ustar benbenpackage com.baselet.element.facet; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.AlignVertical; public class Alignment { private final AlignHorizontal horizontalDefault; private final AlignVertical verticalDefault; private AlignHorizontal horizontal; private boolean horizontalGloballySet; private AlignVertical vertical; private boolean verticalGloballySet; public Alignment(Settings settings) { horizontalDefault = settings.getHAlign(); verticalDefault = settings.getVAlign(); horizontal = horizontalDefault; vertical = verticalDefault; horizontalGloballySet = false; verticalGloballySet = false; } public AlignHorizontal getHorizontal() { return horizontal; } public void setHorizontal(boolean setGlobal, AlignHorizontal horizontal) { if (setGlobal) { horizontalGloballySet = true; this.horizontal = horizontal; } else if (!horizontalGloballySet) { this.horizontal = horizontal; } } public boolean isHorizontalGloballySet() { return horizontalGloballySet; } public AlignVertical getVertical() { return vertical; } public void setVertical(boolean setGlobal, AlignVertical vertical) { if (setGlobal) { verticalGloballySet = true; this.vertical = vertical; } else if (!verticalGloballySet) { this.vertical = vertical; } } public boolean isVerticalGloballySet() { return verticalGloballySet; } public void reset() { setHorizontal(false, horizontalDefault); setVertical(false, verticalDefault); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/NewGridElement.java0000644000175000017500000004400512533641120026433 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import org.apache.log4j.Logger; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementStyle; import com.baselet.control.enums.LineType; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.facet.Facet; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.interfaces.Component; import com.baselet.element.interfaces.DrawHandlerInterface; import com.baselet.element.interfaces.GridElement; import com.baselet.element.interfaces.GridElementDeprecatedAddons; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.Stickable; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.Stickables; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.AutocompletionText; public abstract class NewGridElement implements GridElement { private final Logger log = Logger.getLogger(NewGridElement.class); private DrawHandler drawer; // this is the drawer for element specific stuff private DrawHandler metaDrawer; // this is a separate drawer to draw stickingborder, selection-background etc. private Component component; private DrawHandlerInterface handler; private List panelAttributes; protected PropertiesParserState state; protected final UndoHistory undoStack = new UndoHistory(); public void init(Rectangle bounds, String panelAttributes, String additionalAttributes, Component component, DrawHandlerInterface handler) { this.component = component; drawer = component.getDrawHandler(); metaDrawer = component.getMetaDrawHandler(); setPanelAttributesHelper(panelAttributes); setRectangle(bounds); this.handler = handler; state = new PropertiesParserState(createSettings(), drawer); setAdditionalAttributes(additionalAttributes); } @Override public String getPanelAttributes() { return SharedUtils.listToString("\n", panelAttributes); } @Override public List getPanelAttributesAsList() { return panelAttributes; } @Override public void setPanelAttributes(String panelAttributes) { setPanelAttributesHelper(panelAttributes); updateModelFromText(); } public void setPanelAttributesHelper(String panelAttributes) { this.panelAttributes = Arrays.asList(panelAttributes.split("\n", -1)); // split with -1 to retain empty lines at the end } /** * ugly workaround to avoid that the Resize().execute() call which calls setSize() on this model updates the model during the * calculated model update from autoresize. Otherwise the drawer cache would get messed up (it gets cleaned up 2 times in a row and afterwards everything gets drawn 2 times). * Best testcase is an autoresize element with a background. Write some text and everytime autresize triggers, the background is drawn twice. */ private boolean autoresizePossiblyInProgress = false; @Override public void updateModelFromText() { autoresizePossiblyInProgress = true; drawer.clearCache(); drawer.resetStyle(); // must be set before actions which depend on the fontsize (otherwise a changed fontsize would be recognized too late) try { PropertiesParser.parsePropertiesAndHandleFacets(this, state); } catch (Exception e) { log.info("Cannot parse Properties Text", e); drawer.resetStyle(); String localizedMessage = e.getLocalizedMessage(); if (localizedMessage == null) { localizedMessage = e.toString(); } drawError(drawer, localizedMessage); } autoresizePossiblyInProgress = false; component.afterModelUpdate(); } protected void drawError(DrawHandler drawer, String errorText) { drawer.setEnableDrawing(true); drawer.setForegroundColor(ColorOwn.RED); drawer.setBackgroundColor(ColorOwn.RED.transparency(Transparency.SELECTION_BACKGROUND)); drawer.setLineWidth(0.2); drawer.drawRectangle(0, 0, getRealSize().width, getRealSize().height); // draw dotted rect (to enforce background color even if element has no border) resetAndDrawMetaDrawerContent(metaDrawer); drawer.print(errorText, 3, getRealSize().height * 0.5 - drawer.textHeightMax(), AlignHorizontal.LEFT); } void resetMetaDrawerAndDrawCommonContent(PropertiesParserState state, boolean resetMetaDrawer) { drawCommonContent(state); if (resetMetaDrawer) { resetAndDrawMetaDrawerContent(metaDrawer); } } protected abstract void drawCommonContent(PropertiesParserState state); protected void resetAndDrawMetaDrawerContent(DrawHandler drawer) { drawer.clearCache(); drawer.setForegroundColor(ColorOwn.TRANSPARENT); drawer.setBackgroundColor(ColorOwn.SELECTION_BG); drawer.drawRectangle(0, 0, getRealSize().width, getRealSize().height); if (SharedConfig.getInstance().isDev_mode()) { drawer.setForegroundColor(ColorOwn.BLACK); drawer.setFontSize(10.5); drawer.print(getId().toString(), new PointDouble(getRealSize().width - 3, getRealSize().height - 2), AlignHorizontal.RIGHT); } drawer.resetColorSettings(); if (SharedConfig.getInstance().isShow_stickingpolygon()) { drawStickingPolygon(drawer); } } @Override public void setProperty(String key, Object newValue) { StringBuilder sb = new StringBuilder(""); for (String line : getPanelAttributesAsList()) { if (!line.startsWith(key)) { sb.append(line).append("\n"); } } if (sb.length() > 0) { // remove last linebreak sb.setLength(sb.length() - 1); } if (newValue != null) { sb.append("\n").append(key).append(KeyValueFacet.SEP).append(newValue.toString()); // null will not be added as a value } setPanelAttributes(sb.toString()); } @Override public String getSetting(String key) { for (String line : getPanelAttributesAsList()) { if (line.startsWith(key + KeyValueFacet.SEP)) { String[] split = line.split(KeyValueFacet.SEP, 2); if (split.length > 1) { return split[1]; } } } return null; } @Override public String getAdditionalAttributes() { return ""; // usually GridElements have no additional attributes } @Override public void setAdditionalAttributes(String additionalAttributes) { // usually GridElements have no additional attributes } @Override public boolean isInRange(Rectangle rect1) { return rect1.contains(getRectangle()); } @Override public Set getResizeArea(int x, int y) { Set returnSet = new HashSet(); if (state.getElementStyle() == ElementStyle.NORESIZE || state.getElementStyle() == ElementStyle.AUTORESIZE) { return returnSet; } if (x <= 5 && x >= 0) { returnSet.add(Direction.LEFT); } else if (x <= getRectangle().width && x >= getRectangle().width - 5) { returnSet.add(Direction.RIGHT); } if (y <= 5 && y >= 0) { returnSet.add(Direction.UP); } else if (y <= getRectangle().height && y >= getRectangle().height - 5) { returnSet.add(Direction.DOWN); } return returnSet; } /** * @deprecated use {@link #generateStickingBorder()} instead, because typically the stickingpolygon is created for the own Rectangle, and the other method guarantees that the correct zoom level is applied (important to make alternative StickingPolygonGenerators like PointDoubleStickingPolygonGenerator work) */ @Deprecated @Override public final StickingPolygon generateStickingBorder(Rectangle rect) { return state.getStickingPolygonGenerator().generateStickingBorder(rect); } /** * generates the StickingPolygon of the element using the rectangle as if the zoomlevel would be 100% (this is IMPORTANT because the sticking-calculation doesn't calculate the zoomlevel (see Issue 229 and 231) * Should never be overwritten; if a specific StickingPolygon should be created, instead overwrite the StickingPolygonGenerator in PropertiesParserState eg: Class uses different Generators based on which facets are active (see Class.java) */ @Override public final StickingPolygon generateStickingBorder() { return generateStickingBorder(getRealRectangle()); // ALWAYS generate the stickingBorder as if zoom were 100% } private final void drawStickingPolygon(DrawHandler drawer) { Rectangle rect = new Rectangle(0, 0, getRealSize().width, getRealSize().height); StickingPolygon poly = this.generateStickingBorder(rect); drawer.setLineType(LineType.DASHED); drawer.setForegroundColor(ColorOwn.STICKING_POLYGON); Vector lines = poly.getStickLines(); drawer.drawLines(lines.toArray(new Line[lines.size()])); drawer.setLineType(LineType.SOLID); drawer.resetColorSettings(); } @Override public void setRectangle(Rectangle bounds) { component.setBoundsRect(bounds); } @Override public void setLocationDifference(int diffx, int diffy) { setLocation(getRectangle().x + diffx, getRectangle().y + diffy); } @Override public void setLocation(int x, int y) { Rectangle rect = getRectangle(); rect.setLocation(x, y); component.setBoundsRect(rect); } @Override public void setSize(int width, int height) { if (width != getRectangle().width || height != getRectangle().height) { // only change size if it is really different Rectangle rect = getRectangle(); rect.setSize(width, height); setRectangle(rect); if (!autoresizePossiblyInProgress) { updateModelFromText(); } } } @Override public Rectangle getRectangle() { return component.getBoundsRect(); } @Override public void repaint() { component.repaintComponent(); } /** * @see com.baselet.element.interfaces.GridElement#getRealSize() */ @Override public Dimension getRealSize() { return new Dimension(zoom(getRectangle().width), zoom(getRectangle().height)); } public Rectangle getRealRectangle() { return new Rectangle(zoom(getRectangle().x), zoom(getRectangle().y), zoom(getRectangle().width), zoom(getRectangle().height)); } private int zoom(int val) { return val * SharedConstants.DEFAULT_GRID_SIZE / getGridSize(); } @Override public Component getComponent() { return component; } protected abstract Settings createSettings(); @Override public List getAutocompletionList() { List returnList = new ArrayList(); addAutocompletionTexts(returnList, state.getSettings().getFacetsForFirstRun()); addAutocompletionTexts(returnList, state.getSettings().getFacetsForSecondRun()); return returnList; } private void addAutocompletionTexts(List returnList, List facets) { for (Facet f : facets) { for (AutocompletionText t : f.getAutocompletionStrings()) { returnList.add(t); } } } @Override public Integer getLayer() { return state.getFacetResponse(LayerFacet.class, LayerFacet.DEFAULT_VALUE); } @Override public Integer getGroup() { return state.getFacetResponse(GroupFacet.class, null); } public void handleAutoresize(DimensionDouble necessaryElementDimension, AlignHorizontal alignHorizontal) { double hSpaceLeftAndRight = drawer.getDistanceBorderToText() * 2; double width = necessaryElementDimension.getWidth() + hSpaceLeftAndRight; double height = necessaryElementDimension.getHeight() + drawer.textHeightMax() / 2; Dimension realSize = getRealSize(); double diffw = width - realSize.width; double diffh = height - realSize.height; int diffwInt = SharedUtils.realignTo(false, unzoom(diffw), true, getGridSize()); int diffhInt = SharedUtils.realignTo(false, unzoom(diffh), true, getGridSize()); List directions = null; if (alignHorizontal == AlignHorizontal.LEFT) { directions = Arrays.asList(Direction.RIGHT, Direction.DOWN); } else if (alignHorizontal == AlignHorizontal.RIGHT) { diffwInt = -diffwInt; directions = Arrays.asList(Direction.LEFT, Direction.DOWN); } else if (alignHorizontal == AlignHorizontal.CENTER) { diffwInt = SharedUtils.realignTo(false, diffwInt / 2.0, true, getGridSize()) * 2; directions = Arrays.asList(Direction.RIGHT, Direction.LEFT, Direction.DOWN); } drag(directions, diffwInt, diffhInt, new Point(0, 0), false, true, handler.getStickableMap(), false); } private double unzoom(double diffw) { return diffw / SharedConstants.DEFAULT_GRID_SIZE * getGridSize(); } @Override public void setRectangleDifference(int diffx, int diffy, int diffw, int diffh, boolean firstDrag, StickableMap stickables, boolean undoable) { Rectangle oldRect = getRectangle(); StickingPolygon stickingPolygonBeforeLocationChange = generateStickingBorder(); String oldAddAttr = getAdditionalAttributes(); setRectangle(new Rectangle(oldRect.x + diffx, oldRect.y + diffy, oldRect.getWidth() + diffw, oldRect.getHeight() + diffh)); moveStickables(stickables, undoable, oldRect, stickingPolygonBeforeLocationChange, oldAddAttr); } @Override public void drag(Collection resizeDirection, int diffX, int diffY, Point mousePosBeforeDrag, boolean isShiftKeyDown, boolean firstDrag, StickableMap stickables, boolean undoable) { Rectangle oldRect = getRectangle(); StickingPolygon stickingPolygonBeforeLocationChange = generateStickingBorder(); String oldAddAttr = getAdditionalAttributes(); if (resizeDirection.isEmpty()) { // Move GridElement setLocationDifference(diffX, diffY); } else { // Resize GridElement Rectangle rect = getRectangle(); if (isShiftKeyDown && diagonalResize(resizeDirection)) { // Proportional Resize boolean mouseToRight = diffX > 0 && diffX > diffY; boolean mouseDown = diffY > 0 && diffY > diffX; boolean mouseLeft = diffX < 0 && diffX < diffY; boolean mouseUp = diffY < 0 && diffY < diffX; if (mouseToRight || mouseLeft) { diffY = diffX; } if (mouseDown || mouseUp) { diffX = diffY; } } if (resizeDirection.contains(Direction.LEFT) && resizeDirection.contains(Direction.RIGHT)) { rect.setX(rect.getX() - diffX / 2); rect.setWidth(Math.max(rect.getWidth() + diffX, minSize())); } else if (resizeDirection.contains(Direction.LEFT)) { int newWidth = rect.getWidth() - diffX; if (newWidth >= minSize()) { rect.setX(rect.getX() + diffX); rect.setWidth(newWidth); } } else if (resizeDirection.contains(Direction.RIGHT)) { rect.setWidth(Math.max(rect.getWidth() + diffX, minSize())); } if (resizeDirection.contains(Direction.UP)) { int newHeight = rect.getHeight() - diffY; if (newHeight >= minSize()) { rect.setY(rect.getY() + diffY); rect.setHeight(newHeight); } } if (resizeDirection.contains(Direction.DOWN)) { rect.setHeight(Math.max(rect.getHeight() + diffY, minSize())); } setRectangle(rect); if (!autoresizePossiblyInProgress) { updateModelFromText(); } } moveStickables(stickables, undoable, oldRect, stickingPolygonBeforeLocationChange, oldAddAttr); } private void moveStickables(StickableMap stickables, boolean undoable, Rectangle oldRect, StickingPolygon stickingPolygonBeforeLocationChange, String oldAddAttr) { Map> stickableChanges = Stickables.moveStickPointsBasedOnPolygonChanges(stickingPolygonBeforeLocationChange, generateStickingBorder(), stickables, getGridSize()); if (undoable) { undoStack.add(new UndoInformation(getRectangle(), oldRect, stickableChanges, getGridSize(), oldAddAttr, getAdditionalAttributes())); } } @Override public void dragEnd() { // only used by some specific elements like Relations } @Override public boolean isSelectableOn(Point point) { return getRectangle().contains(point); } private boolean diagonalResize(Collection resizeDirection) { return resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.RIGHT) || resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.LEFT) || resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.LEFT) || resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.RIGHT); } protected DrawHandlerInterface getHandler() { return handler; } public int getGridSize() { return getHandler().getGridSize(); } private int minSize() { return handler.getGridSize() * 2; } @Override public void undoDrag() { execUndoInformation(true); } private void execUndoInformation(boolean undo) { UndoInformation undoInfo = undoStack.get(undo); if (undoInfo != null) { setRectangle(getRectangle().add(undoInfo.getDiffRectangle(getGridSize(), undo))); Stickables.applyChanges(undoInfo.getStickableMoves(undo), null); setAdditionalAttributes(undoInfo.getAdditionalAttributes(undo)); } } @Override public void redoDrag() { execUndoInformation(false); } @Override public void mergeUndoDrag() { UndoInformation undoInfoA = undoStack.remove(); UndoInformation undoInfoB = undoStack.remove(); undoStack.add(undoInfoA.merge(undoInfoB)); } @Override public GridElementDeprecatedAddons getDeprecatedAddons() { return GridElementDeprecatedAddons.NONE; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/UndoHistory.java0000644000175000017500000000226212533641120026050 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; public class UndoHistory { private final Logger log = Logger.getLogger(UndoHistory.class); private final List history = new ArrayList(); private int currentIndex = -1; public void add(UndoInformation undoInformation) { while (history.size() > currentIndex + 1) { history.remove(history.size() - 1); } history.add(undoInformation); currentIndex++; } public UndoInformation remove() { UndoInformation undoInformation = history.remove(currentIndex); currentIndex = Math.min(currentIndex, history.size() - 1); // stay at current index except if it was pointing to the last element return undoInformation; } public UndoInformation get(boolean undo) { if (history.isEmpty()) { return null; } if (!undo) { currentIndex++; } UndoInformation undoInformation = history.get(currentIndex); log.trace("GET " + currentIndex + " = " + undoInformation.getDiffRectangle(10, undo) + "/size" + history.size()); if (undo) { currentIndex--; } return undoInformation; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/UndoInformation.java0000644000175000017500000001307212533641120026675 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.Stickable; public class UndoInformation { private final Rectangle diffRect; private final Map> stickableMoves; private final String oldAdditionalAttributes; private final String newAdditionalAttributes; private UndoInformation(Rectangle diffRect, Map> stickableMoves, String oldAdditionalAttributes, String newAdditionalAttributes) { this.diffRect = diffRect; this.stickableMoves = stickableMoves; this.oldAdditionalAttributes = oldAdditionalAttributes; this.newAdditionalAttributes = newAdditionalAttributes; } public UndoInformation(Rectangle newRect, Rectangle oldRect, Map> stickableMoves, int gridSize, String oldAdditionalAttributes, String newAdditionalAttributes) { this(toMinZoom(newRect.subtract(oldRect), gridSize), stickableMoves, oldAdditionalAttributes, newAdditionalAttributes); } private static Map> invertStickableMoves(Map> stickableMoves) { Map> invertedMap = new HashMap>(); for (Entry> entry : stickableMoves.entrySet()) { List invList = new ArrayList(); for (PointChange p : entry.getValue()) { invList.add(new PointChange(p.getIndex(), -p.getDiffX(), -p.getDiffY())); } invertedMap.put(entry.getKey(), invList); } return invertedMap; } public Rectangle getDiffRectangle(int gridSize, boolean undo) { Rectangle returnRect = undo ? diffRect.copyInverted() : diffRect; return toCurrentZoom(returnRect, gridSize); } public Map> getStickableMoves(boolean undo) { return undo ? invertStickableMoves(stickableMoves) : stickableMoves; } public String getAdditionalAttributes(boolean undo) { if (undo) { return oldAdditionalAttributes; } else { return newAdditionalAttributes; } } private static Rectangle toMinZoom(Rectangle rectangle, int gridSize) { int xBefore = toMinZoom(rectangle.getX(), gridSize); int yBefore = toMinZoom(rectangle.getY(), gridSize); int wBefore = toMinZoom(rectangle.getWidth(), gridSize); int hBefore = toMinZoom(rectangle.getHeight(), gridSize); return new Rectangle(xBefore, yBefore, wBefore, hBefore); } private static int toMinZoom(int val, int gridSize) { return val / gridSize; } private static Rectangle toCurrentZoom(Rectangle rectangle, int gridSize) { int xBefore = toCurrentZoom(rectangle.getX(), gridSize); int yBefore = toCurrentZoom(rectangle.getY(), gridSize); int wBefore = toCurrentZoom(rectangle.getWidth(), gridSize); int hBefore = toCurrentZoom(rectangle.getHeight(), gridSize); return new Rectangle(xBefore, yBefore, wBefore, hBefore); } private static int toCurrentZoom(int val, int gridSize) { return val * gridSize; } public UndoInformation merge(UndoInformation other) { Rectangle mergedUndoDiffRect = diffRect.add(other.diffRect); Map> mergedMap = new HashMap>(); mergeStickableMoves(mergedMap, stickableMoves); mergeStickableMoves(mergedMap, other.stickableMoves); return new UndoInformation(mergedUndoDiffRect, mergedMap, other.oldAdditionalAttributes, newAdditionalAttributes); } private void mergeStickableMoves(Map> targetMap, Map> sourceMap) { for (Entry> sourceEntry : sourceMap.entrySet()) { Stickable sourceStickable = sourceEntry.getKey(); List sourceChangeList = sourceEntry.getValue(); List targetPointChanges = targetMap.get(sourceStickable); if (targetPointChanges == null) { // stickable was not moved before in targetMap targetMap.put(sourceStickable, sourceChangeList); } else { // stickable was already moved and these moves must be merged mergeSourceToTarget(sourceChangeList, targetPointChanges); } } } private void mergeSourceToTarget(List sourceChangeList, List targetPointChanges) { for (PointChange sourceChange : sourceChangeList) { mergePoint(targetPointChanges, sourceChange); } } private void mergePoint(List targetPointChanges, PointChange sourceChange) { for (ListIterator iter = targetPointChanges.listIterator(); iter.hasNext();) { PointChange targetChange = iter.next(); if (sourceChange.getIndex().equals(targetChange.getIndex())) { iter.set(new PointChange(targetChange.getIndex(), sourceChange.getDiffX() + targetChange.getDiffX(), sourceChange.getDiffY() + targetChange.getDiffY())); return; // index already in targetList and successfully updated } } targetPointChanges.add(sourceChange); // index not in targetList, therefore added here } public String toString(boolean undo) { return "UndoInformation [diffRect=" + getDiffRectangle(SharedConstants.DEFAULT_GRID_SIZE, undo) + ", stickableMoves=" + SharedUtils.mapToString(getStickableMoves(undo)) + ", additionalAttributes=" + getAdditionalAttributes(undo) + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/0000755000175000017500000000000012533641120025037 5ustar benben././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/GridElementDeprecatedAddons.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/GridElementDeprecate0000644000175000017500000000041512533641120030776 0ustar benbenpackage com.baselet.element.interfaces; public interface GridElementDeprecatedAddons { void doBeforeExport(); public static final GridElementDeprecatedAddons NONE = new GridElementDeprecatedAddons() { @Override public void doBeforeExport() {} }; } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/Component.java0000644000175000017500000000056612533641120027653 0ustar benbenpackage com.baselet.element.interfaces; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.draw.DrawHandler; public interface Component { void setBoundsRect(Rectangle rect); Rectangle getBoundsRect(); void repaintComponent(); DrawHandler getDrawHandler(); DrawHandler getMetaDrawHandler(); void afterModelUpdate(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/GridElement.java0000644000175000017500000000417712533641120030112 0ustar benbenpackage com.baselet.element.interfaces; import java.util.Collection; import java.util.List; import java.util.Set; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementId; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.StickingPolygon; public interface GridElement extends HasPanelAttributes { void setRectangle(Rectangle bounds); Integer getGroup(); void setLocationDifference(int diffx, int diffy); String getAdditionalAttributes(); void setAdditionalAttributes(String additionalAttributes); void setLocation(int x, int y); void setSize(int width, int height); Set getResizeArea(int x, int y); StickingPolygon generateStickingBorder(Rectangle rect); StickingPolygon generateStickingBorder(); /** * position of the element on the drawpanel. * x and y: distance from the upper left corner of the drawpanel. * width and height: size of the element. * */ Rectangle getRectangle(); void repaint(); /** * @return size of the element as if the zoomlevel would be 100% (eg: if zoom is 80% and width is 80 it would be returned as 100) */ Dimension getRealSize(); boolean isInRange(Rectangle rectangle); Component getComponent(); void setProperty(String key, Object newValue); void updateModelFromText(); String getSetting(String key); Integer getLayer(); ElementId getId(); void drag(Collection resizeDirection, int diffX, int diffY, Point mousePosBeforeDrag, boolean isShiftKeyDown, boolean firstDrag, StickableMap stickables, boolean undoable); boolean isSelectableOn(Point point); void dragEnd(); List getPanelAttributesAsList(); void setRectangleDifference(int diffx, int diffy, int diffw, int diffh, boolean firstDrag, StickableMap stickables, boolean undoable); void undoDrag(); void redoDrag(); void mergeUndoDrag(); GridElementDeprecatedAddons getDeprecatedAddons(); } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/HasPanelAttributes.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/HasPanelAttributes.j0000644000175000017500000000045312533641120030756 0ustar benbenpackage com.baselet.element.interfaces; import java.util.List; import com.baselet.gui.AutocompletionText; public interface HasPanelAttributes { String getPanelAttributes(); void setPanelAttributes(String panelAttributes); List getAutocompletionList(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/Diagram.java0000644000175000017500000000124712533641120027252 0ustar benbenpackage com.baselet.element.interfaces; import java.util.Collection; import java.util.List; import com.baselet.element.sticking.Stickable; import com.baselet.element.sticking.StickableMap; public interface Diagram extends HasPanelAttributes, HasGridElements { public abstract List getStickables(); public abstract StickableMap getStickables(GridElement draggedElement); public abstract StickableMap getStickables(GridElement draggedElement, Collection excludeList); public abstract List getGridElementsByLayerLowestToHighest(); public abstract List getGridElementsByLayer(boolean ascending); } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/DrawHandlerInterface.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/DrawHandlerInterface0000644000175000017500000000040612533641120030776 0ustar benbenpackage com.baselet.element.interfaces; import com.baselet.element.sticking.StickableMap; public interface DrawHandlerInterface { void updatePropertyPanel(); int getGridSize(); StickableMap getStickableMap(); boolean isInitialized(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/interfaces/HasGridElements.java0000644000175000017500000000023012533641120030713 0ustar benbenpackage com.baselet.element.interfaces; import java.util.List; public interface HasGridElements { public List getGridElements(); }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/0000755000175000017500000000000012533641120025057 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/ElementFactory.java0000644000175000017500000000431612533641120030647 0ustar benbenpackage com.baselet.element.elementnew; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.elementnew.plot.PlotGrid; import com.baselet.element.elementnew.uml.ActivityObject; import com.baselet.element.elementnew.uml.Actor; import com.baselet.element.elementnew.uml.Class; import com.baselet.element.elementnew.uml.Deployment; import com.baselet.element.elementnew.uml.Frame; import com.baselet.element.elementnew.uml.Generic; import com.baselet.element.elementnew.uml.Hierarchy; import com.baselet.element.elementnew.uml.Interface; import com.baselet.element.elementnew.uml.Note; import com.baselet.element.elementnew.uml.Package; import com.baselet.element.elementnew.uml.SpecialState; import com.baselet.element.elementnew.uml.State; import com.baselet.element.elementnew.uml.SyncBarHorizontal; import com.baselet.element.elementnew.uml.SyncBarVertical; import com.baselet.element.elementnew.uml.Timer; import com.baselet.element.elementnew.uml.UseCase; import com.baselet.element.relation.Relation; public abstract class ElementFactory { protected static NewGridElement createAssociatedGridElement(ElementId id) { switch (id) { case PlotGrid: return new PlotGrid(); case Relation: return new Relation(); case Text: return new Text(); case UMLActor: return new Actor(); case UMLClass: return new Class(); case UMLDeployment: return new Deployment(); case UMLFrame: return new Frame(); case UMLGeneric: return new Generic(); case UMLInterface: return new Interface(); case UMLNote: return new Note(); case UMLObject: return new ActivityObject(); case UMLPackage: return new Package(); case UMLSpecialState: return new SpecialState(); case UMLState: return new State(); case UMLSyncBarHorizontal: return new SyncBarHorizontal(); case UMLSyncBarVertical: return new SyncBarVertical(); case UMLTimer: return new Timer(); case UMLUseCase: return new UseCase(); case UMLHierarchy: return new Hierarchy(); default: throw new RuntimeException("Unknown class id: " + id); } } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/Text.java0000644000175000017500000000133012533641120026643 0ustar benbenpackage com.baselet.element.elementnew; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsText; import com.baselet.element.sticking.polygon.NoStickingPolygonGenerator; public class Text extends NewGridElement { @Override protected Settings createSettings() { return new SettingsText(); } @Override public ElementId getId() { return ElementId.Text; } @Override protected void drawCommonContent(PropertiesParserState state) { state.setStickingPolygonGenerator(NoStickingPolygonGenerator.INSTANCE); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/0000755000175000017500000000000012533641120026035 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/0000755000175000017500000000000012533641120027331 5ustar benben././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/ParserException.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/ParserEx0000644000175000017500000000150612533641120031007 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.Arrays; public class ParserException extends RuntimeException { private static final long serialVersionUID = 1L; public ParserException() { super("Unknown Error"); } public ParserException(String message) { super(message); } public ParserException(String key, String value, int line) { this("Invalid assignment: \"" + key + "=" + value + "\" (line: " + line + ")"); } public ParserException(String key, String value, int line, String additionalInfo) { this("Invalid assignment: \"" + key + "=" + value + "\" (line: " + line + ") [" + additionalInfo + "]"); } public ParserException(String key, String[] values, int line) { this("The following values are colliding: \"" + key + "=" + Arrays.asList(values) + "\" (line: " + line + ")"); } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/KeyValue.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/KeyValue0000644000175000017500000000150012533641120030775 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; public class KeyValue { private String key; private String value; private int line; private boolean used; public KeyValue(String key, String value, int line) { super(); this.key = key; this.value = value; this.line = line; used = false; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public int getLine() { return line; } public void setLine(int line) { this.line = line; } public boolean isUsed() { return used; } public void setUsed(boolean used) { this.used = used; } @Override public String toString() { return key + "\t-> " + value + " (line " + line + ")"; } } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/PlotConstants.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/PlotCons0000644000175000017500000001753712533641120031032 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.gui.AutocompletionText; public class PlotConstants { /** Shared Value Constants **/ // Some key->value assignments have a list as value and the following separator is used to separate the list entries public static final String VALUE_LIST_SEPARATOR = ","; public static final String KEY_VALUE_SEP = "="; // If a variable is set to DEFAULT_VALUE, it gets removed from the parsers plotValuesCache, therefore the DEFAULT is used again public static final String DEFAULT_VALUE = "auto"; /** Parser Constants **/ public static final String PLOT = "plot"; public static final String DATA = "data"; public static final String REGEX_COMMENT = "(//.*)"; public static final String REGEX_KEY = "([(\\w)\\.]+)"; // a value is a comma separated list of word characters or "-" (for negative int eg: min_val=-3) or # (for color decoding) or . (for hierarchies) public static final String REGEX_VALUE = "([-(\\w)#\\." + VALUE_LIST_SEPARATOR + "]*)"; public static final String REGEX_VALUE_ASSIGNMENT = "(" + REGEX_KEY + KEY_VALUE_SEP + REGEX_VALUE + ")"; // plot followed by an optional space or plot followed by 1 or more value assignments (values which are only valid for the plot) public static final String REGEX_PLOT = "((" + PLOT + " ?)|(" + PLOT + " (" + REGEX_VALUE_ASSIGNMENT + " )*" + REGEX_VALUE_ASSIGNMENT + "))"; // +plot (overlap plots) followed by an optional space or plot followed by 1 or more value assignments (values which are only valid for the plot) public static final String REGEX_PLOT_ADD = "(\\+" + REGEX_PLOT + ")"; // data followed by an optional space or by space and a name which consists of word characters public static final String REGEX_DATA = "((" + DATA + " ?)|(" + DATA + " (\\w)+))"; // 1 non-comment-line which contains at least 1 Tab is an interpreted dataset public static final String REGEX_DATA_SEPARATOR = "([\t ]+)"; public static final String REGEX_DATA_GUESS = "((?!(" + REGEX_COMMENT + "))(([^=]+)|(.*" + REGEX_DATA_SEPARATOR + ".*)))"; // The following line is needed to color everything which doesn't match another RegEx // public static final String REGEX_COLOR_BASE = "(?!((" + REGEX_COMMENT + ")|(" + PLOT + ")|(" + REGEX_VALUE_ASSIGNMENT + "))).*"; /* The following variables are automatically parsed for the autocompletion. Therefore some conventions must be made: 1.) The possible values of a key must be listed in the following lines or they will not be recognized by the autocompletion 2.) Every key is separated in 3 parts: KEY__. can be STRING,INT,LIST,BOOL (in future there may be more types) 3.) If there is a limited number of possible values it must be named: _ where must match the tag in the key 4.) values with _DEFAULT at the end are ignored by the autocompletion. */ /** Plotgrid Value Constants **/ public static final String KEY_INT_GRID_WIDTH = "grid.width"; public static final String GRID_WIDTH_DEFAULT = "3"; /** Plot Value Constants **/ public static final String KEY_BOOL_DATA_INVERT = "data.invert"; public static final Boolean DATA_INVERT_DEFAULT = false; public static final String KEY_BOOL_PLOT_TILT = "tilt"; public static final Boolean PLOT_TILT_DEFAULT = false; public static final String KEY_INT_X_POSITION = "pos.x"; // DEFAULT: filling grid from upper left to lower right corner public static final String KEY_INT_Y_POSITION = "pos.y"; public static final String KEY_INT_MIN_VALUE = "value.min"; // DEFAULT: the lowest/highest value in the plot public static final String MIN_VALUE_ALL = "all"; public static final String KEY_INT_MAX_VALUE = "value.max"; public static final String MAX_VALUE_ALL = "all"; public static final String KEY_LIST_COLORS = "colors"; // DEFAULT: cycling through colors-list public static final List COLORS_DEFAULT = Arrays.asList("red", "blue", "green", "orange", "cyan", "magenta", "pink"); public static interface PlotSetting { public String getValue(); } public static enum PlotType implements PlotSetting { Bar, Line, Pie, Scatter; @Override public String getValue() { return toString().toLowerCase(); } public static String getKey() { return "type"; } } public static enum AxisShow implements PlotSetting { Axis, Line, Marker, Text, Nothing(""); private final String value; AxisShow() { value = toString().toLowerCase(); } public static String getValueList() { return KEY_VALUE_SEP + AxisShow.Axis.getValue() + VALUE_LIST_SEPARATOR + AxisShow.Line.getValue() + VALUE_LIST_SEPARATOR + AxisShow.Marker.getValue() + VALUE_LIST_SEPARATOR + AxisShow.Text.getValue(); } AxisShow(String value) { this.value = value; } @Override public String getValue() { return value; } public static String getKeyValueAxis() { return "axis.value.show"; } public static String getKeyDescAxis() { return "axis.desc.show"; } } public static enum AxisList implements PlotSetting { Relevant, Nothing(""); private final String value; AxisList() { value = toString().toLowerCase(); } AxisList(String value) { this.value = value; } @Override public String getValue() { return value; } public static String getKey() { return "axis.value.list"; } } public static List toStringList(PlotSetting[] input) { return toStringList(Arrays.asList(input)); } public static List toStringList(List input) { List returnList = new ArrayList(); for (PlotSetting o : input) { returnList.add(o.getValue()); } return returnList; } public static final List AUTOCOMPLETION_LIST = Arrays.asList( new AutocompletionText(PLOT, "draws the configured plot"), new AutocompletionText(DATA, "marks everything until the next empty line as dataset"), new AutocompletionText(DATA + KEY_VALUE_SEP + "", "as data but with explicit name"), new AutocompletionText(KEY_INT_GRID_WIDTH + KEY_VALUE_SEP + GRID_WIDTH_DEFAULT, "sets the amount of plots per line"), new AutocompletionText(KEY_BOOL_DATA_INVERT + KEY_VALUE_SEP + DATA_INVERT_DEFAULT, "inverts the dataset"), new AutocompletionText(KEY_BOOL_PLOT_TILT + KEY_VALUE_SEP + PLOT_TILT_DEFAULT, "tilts the plot"), new AutocompletionText(KEY_INT_X_POSITION + KEY_VALUE_SEP + "", "places the next plot at specific horizontal grid position"), new AutocompletionText(KEY_INT_Y_POSITION + KEY_VALUE_SEP + "", "places the next plot at specific vertical grid position"), new AutocompletionText(KEY_INT_MIN_VALUE + KEY_VALUE_SEP + MIN_VALUE_ALL, "restrict the highest value shown in the plot"), new AutocompletionText(KEY_INT_MAX_VALUE + KEY_VALUE_SEP + MAX_VALUE_ALL, "restrict the lowest value shown in the plot"), new AutocompletionText(KEY_LIST_COLORS + KEY_VALUE_SEP + COLORS_DEFAULT.get(0) + VALUE_LIST_SEPARATOR + COLORS_DEFAULT.get(1), "sets a list of colors which will be cycled by the plot"), new AutocompletionText(PlotType.getKey() + KEY_VALUE_SEP + PlotType.Bar.getValue(), "sets the plot type to Bar plot"), new AutocompletionText(PlotType.getKey() + KEY_VALUE_SEP + PlotType.Line.getValue(), "sets the plot type to Line plot"), new AutocompletionText(PlotType.getKey() + KEY_VALUE_SEP + PlotType.Pie.getValue(), "sets the plot type to Pie plot"), new AutocompletionText(PlotType.getKey() + KEY_VALUE_SEP + PlotType.Scatter.getValue(), "sets the plot type to Scatter plot"), new AutocompletionText(AxisShow.getKeyValueAxis() + AxisShow.getValueList(), "a list of elements to show at the value axis"), new AutocompletionText(AxisShow.getKeyDescAxis() + AxisShow.getValueList(), "a list of elements to show at the description axis"), new AutocompletionText(AxisList.getKey() + KEY_VALUE_SEP + AxisList.Relevant.getValue(), "restricts shown values to occurring ones") ); } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/DataSet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/DataSet.0000644000175000017500000001214012533641120030655 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.Matrix; public class DataSet { private String id; private Integer nr; private int lineNr; private boolean isInverted; private List titleRow = null; private List titleCol = null; private Matrix valueMatrix; private Matrix analyseMatrix; public static final Double VALUE_DEFAULT = 0.0; // used for invalid value fields or missing fields protected DataSet(String id, int nr, int lineNr) { this.id = id; this.nr = nr; this.lineNr = lineNr; analyseMatrix = new Matrix(); } public String getId() { return id; } public Integer getNr() { return nr; } public int getLineNr() { return lineNr; } /** * @return the row size */ public int rows() { return valueMatrix.rows(); } /** * @return the column size */ public int cols() { return valueMatrix.cols(); } public boolean isEmpty() { return valueMatrix.isEmpty(); } /** * @param index * the index of the row * @return a Double[] containing the cells of the row */ public Double[] row(int index) { List list = valueMatrix.row(index); return list.toArray(new Double[list.size()]); } public Double[][] data() { if (valueMatrix.isEmpty()) { throw new ParserException("The dataset (line: " + getLineNr() + ") has no values"); } Double[][] returnArray = new Double[rows()][]; for (int i = 0; i < rows(); i++) { returnArray[i] = row(i); } return returnArray; } /** * Changed the manual inversion of the dataset. The dataset must only be inverted if the value has changed because * it is only referenced from plots, therefore the last inversion will be dragged to further plot-calls without a problem */ public void setInvert(boolean shouldBeInverted) { if (isInverted == !shouldBeInverted) { analyseMatrix.invert(); separateTitleRowColFromContent(); isInverted = shouldBeInverted; } } public String[] titleRow() { return titleRow.toArray(new String[titleRow.size()]); } public String[] titleCol() { return titleCol.toArray(new String[titleCol.size()]); } @Override public String toString() { return "Dataset (" + id + ")\n" + analyseMatrix; } protected void addLine(String[] line) { analyseMatrix.addLine(new ArrayList(Arrays.asList(line))); } protected void analyseMatrix() { separateTitleRowColFromContent(); // If the valuematrix has more rows than cols the analyseMatrix must be inverted and analysed again // if (!valueMatrix.isEmpty() && valueMatrix.hasMoreRowsThanCols()) analyseMatrix.invert(); // separateTitleRowColFromContent(); } private void separateTitleRowColFromContent() { if (analyseMatrix.isEmpty()) { throw new ParserException("The dataset (line: " + getLineNr() + ") has no content"); } List firstRow = analyseMatrix.row(0); List firstCol = analyseMatrix.col(0); boolean hasTitleRow = isTitleLine(firstRow); boolean hasTitleCol = isTitleLine(firstCol); if (hasTitleRow && hasTitleCol) { if (!firstRow.get(0).isEmpty() || !firstCol.get(0).isEmpty()) { throw new ParserException("If a dataset has a title row and column, the upper left space must be empty"); } titleRow = firstRow.subList(1, firstRow.size()); // ignore first cell titleCol = firstCol.subList(1, firstCol.size()); // ignore first cell } else if (hasTitleRow && !hasTitleCol) { titleRow = firstRow; titleCol = createEmptyList(firstCol.size() - 1); } else if (!hasTitleRow && hasTitleCol) { titleRow = createEmptyList(firstRow.size() - 1); titleCol = firstCol; } else /* if (!hasTitleRow && !hasTitleCol) */{ titleRow = createEmptyList(firstRow.size()); titleCol = createEmptyList(firstCol.size()); } valueMatrix = new Matrix(); for (int r = hasTitleRow ? 1 : 0; r < analyseMatrix.rows(); r++) { List row = analyseMatrix.row(r); List rowDouble = new ArrayList(); for (int c = hasTitleCol ? 1 : 0; c < row.size(); c++) { String val = row.get(c); try { if (val == null) { throw new NumberFormatException(); } else { rowDouble.add(Double.parseDouble(val)); } } catch (NumberFormatException ex) { throw new ParserException("The Dataset (line: " + getLineNr() + ") contains invalid values"); } } valueMatrix.addLine(rowDouble); } } private boolean isTitleLine(List row) { int numbersInRow = 0; for (String cell : row) { if (cell == null) { continue; } try { Double.parseDouble(cell); numbersInRow++; } catch (NumberFormatException ex) {/* do nothing */} } return row.size() - numbersInRow > numbersInRow; } private List createEmptyList(int size) { List returnList = new ArrayList(); for (int i = 0; i < size; i++) { returnList.add(""); } return returnList; } } ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/ParserResult.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/ParserRe0000644000175000017500000000372112533641120031002 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.ArrayList; import java.util.HashMap; import com.baselet.diagram.draw.DrawHandler; public class ParserResult { private DrawHandler drawer; private final ArrayList plotStateList; // These are few variables which influence the plotgrid private final HashMap plotGridValues; public ParserResult() { plotStateList = new ArrayList(); plotGridValues = new HashMap(); } public void setDrawer(DrawHandler drawer) { this.drawer = drawer; } public DrawHandler getDrawer() { return drawer; } public ArrayList getPlotStateList() { return plotStateList; } public String getPlotGridValue(String key, String defaultValue) { KeyValue keyValue = plotGridValues.get(key); if (keyValue != null) { keyValue.setUsed(true); } if (keyValue == null || keyValue.getValue().equals(PlotConstants.DEFAULT_VALUE)) { return defaultValue; } else { return keyValue.getValue(); } } protected void addPlotState(PlotState plotState) { plotStateList.add(plotState); } protected void addPlotGridValue(String key, KeyValue value) { plotGridValues.put(key, value); } protected void removePlotGridValue(String key) { plotGridValues.remove(key); } @Override public String toString() { StringBuilder sb = new StringBuilder("\n-----------------------------\n"); sb.append("--------PARSER CONTENT-------\n"); sb.append("-----------------------------\n\n"); sb.append("##########PlotStates#########\n\n"); for (PlotState plotState : plotStateList) { sb.append(plotState.toString()).append("\n"); } sb.append("#########PlotGridValues########\n\n"); for (String key : plotGridValues.keySet()) { sb.append("\t").append(key).append(" -> ").append(plotGridValues.get(key)).append("\n"); } sb.append("\n-----------------------------\n"); sb.append("-----------------------------\n"); return sb.toString(); } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/Parser.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/Parser.j0000644000175000017500000001776312533641120030756 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map.Entry; import org.apache.log4j.Logger; public class Parser { private static final Logger log = Logger.getLogger(Parser.class); // The parserResult contains every information which is relevant after input parsing is finished private final ParserResult parserResult; // The following fields are only used during parsing but never referenced after parsing is finished // The values HashsMap contains the actual state of key->value assignments which is copied to every plot at its time of creation private final HashMap tempPlotValuesCache; // The datasetNr is used for sequential naming of not explicitly named datasets private int datasetNr = 1; // The datasetlist is filled during parsing. After parsing every plot gets its dataset injected private final ArrayList datasetList; public Parser() { parserResult = new ParserResult(); datasetList = new ArrayList(); tempPlotValuesCache = new HashMap(); } public ParserResult parse(String source) { List inputList = Arrays.asList(source.split("\n", -1)); ListIterator inputIterator = inputList.listIterator(); while (inputIterator.hasNext()) { String line = inputIterator.next(); if (line.isEmpty() || line.matches(PlotConstants.REGEX_COMMENT)) {/* ignore empty lines and comments */} else if (line.matches(PlotConstants.REGEX_PLOT)) { parserResult.addPlotState(createPlotStateObject(line.split(" "), inputIterator)); } else if (line.matches(PlotConstants.REGEX_PLOT_ADD)) { List plotStates = parserResult.getPlotStateList(); if (plotStates.isEmpty()) { // if no plotStates, create a new one parserResult.addPlotState(createPlotStateObject(line.split(" "), inputIterator)); } else { // if plots exist, add new plotState to last plotState PlotState last = plotStates.get(plotStates.size() - 1); last.addSubPlot(createPlotStateObject(line.split(" "), inputIterator)); } } else if (line.matches(PlotConstants.REGEX_DATA)) { createDatasetObject(line.split(" "), inputIterator); } else if (line.matches(PlotConstants.REGEX_DATA_GUESS)) { inputIterator.previous(); // Must go 1 step back to avoid skipping the first line in createDatasetObject createDatasetObject(new String[] { PlotConstants.DATA }, inputIterator); } else if (line.matches(PlotConstants.REGEX_VALUE_ASSIGNMENT)) { createKeyValueAssignment(line, inputIterator.nextIndex()); } else { throw new ParserException("Invalid line: " + line + "(line: " + inputIterator.nextIndex() + ")"); } } analyseDatasets(); addDatasetsToPlotStates(); return parserResult; } /** * Is called after parsing everything to analyse the dataset content */ private void analyseDatasets() { for (DataSet dataset : datasetList) { dataset.analyseMatrix(); } } /** * Is called after parsing everything to fill datasets in each plotState Object */ private void addDatasetsToPlotStates() { if (datasetList.isEmpty()) { throw new ParserException("You must specify at least one dataset."); } int actualAutoDatasetNr = 0; for (PlotState plotState : parserResult.getPlotStateList()) { actualAutoDatasetNr = addDataset(plotState, actualAutoDatasetNr); // also add datasets to subplots for (PlotState subPlotState : plotState.getSubplots()) { log.info("Add dataset for subplot"); actualAutoDatasetNr = addDataset(subPlotState, actualAutoDatasetNr); } } } private int addDataset(PlotState plotState, int actualAutoDatasetNr) { String datasetId = plotState.getValue(PlotConstants.DATA, null); if (datasetId == null) { if (actualAutoDatasetNr >= datasetList.size()) { actualAutoDatasetNr = 0; } plotState.setDataSet(datasetList.get(actualAutoDatasetNr++)); } else { DataSet dataset = null; if (datasetId.startsWith("#")) { String datasetNr = datasetId.substring(1); for (DataSet tempDataset : datasetList) { if (datasetNr.equals(String.valueOf(tempDataset.getNr()))) { dataset = tempDataset; } } } else { for (DataSet tempDataset : datasetList) { if (datasetId.equals(tempDataset.getId())) { dataset = tempDataset; } } } if (dataset != null) { plotState.setDataSet(dataset); } else { throw new ParserException(PlotConstants.DATA, datasetId, plotState.getLine(PlotConstants.DATA)); } } return actualAutoDatasetNr; } /** * Creates a dataset with the second argument as its id (if it has no such parameter it gets a generated id) * This method is called if the input string starts with "data" or if the input string contains a tab (then a dataset is assumed) * All lines until the next empty line are part of the dataset * * @param args any parameters to the data command including the command itself as first parameter */ private void createDatasetObject(String[] args, ListIterator inputIterator) { int lineNr = inputIterator.nextIndex(); String datasetId = null; if (args != null) { if (args.length > 1) { datasetId = args[1]; /* handle further parameters here */ } } DataSet newDataset = new DataSet(datasetId, datasetNr++, lineNr); while (inputIterator.hasNext()) { String nextLine = inputIterator.next(); if (nextLine.matches(PlotConstants.REGEX_COMMENT)) { continue; } else if (nextLine.trim().isEmpty()) { break; } else { newDataset.addLine(nextLine.split(PlotConstants.REGEX_DATA_SEPARATOR)); } } if (datasetId != null) { for (DataSet ds : datasetList) { if (datasetId.equals(ds.getId())) { throw new ParserException("The dataset name \"" + datasetId + "\" (line: " + lineNr + ") already exists"); } } } datasetList.add(newDataset); } /** * Creates a plotValues Object which contains the dataset as its second argument (if it has no such parameter it cycles through all datasets) * This method is called if the input string starts with "plot". All values which are stored in the parser are copied to the plot * * @param args any parameters to the data command including the command itself as first parameter */ private PlotState createPlotStateObject(String[] args, ListIterator inputIterator) { int lineNr = inputIterator.nextIndex(); HashMap localCopyOfValuesCache = copyHashMap(tempPlotValuesCache); if (args != null) { // Arguments are handled as any other key->value assignment but are only valid for this plot for (int i = 1; i < args.length; i++) { String[] split = args[i].split("="); if (split.length == 1) { split = new String[] { split[0], "" }; } localCopyOfValuesCache.put(split[0], new KeyValue(split[0], split[1], lineNr)); } } // If no dataset is specified the data-value is set to auto if (localCopyOfValuesCache.get(PlotConstants.DATA) == null) { localCopyOfValuesCache.put(PlotConstants.DATA, new KeyValue(PlotConstants.DATA, PlotConstants.DEFAULT_VALUE, lineNr)); } PlotState newPlotState = new PlotState(lineNr, localCopyOfValuesCache); return newPlotState; } /** * Adds a key->value assignment to the values HashMap */ private void createKeyValueAssignment(String line, int lineNr) { String[] split = line.split("="); if (split.length == 1) { split = new String[] { split[0], "" }; } if (split[0].matches(PlotConstants.KEY_INT_GRID_WIDTH)) { parserResult.addPlotGridValue(split[0], new KeyValue(split[0], split[1], lineNr)); } else { tempPlotValuesCache.put(split[0], new KeyValue(split[0], split[1], lineNr)); } } private HashMap copyHashMap(HashMap inputHashMap) { HashMap returnHashMap = new HashMap(); for (Entry entry : inputHashMap.entrySet()) { returnHashMap.put(entry.getKey(), entry.getValue()); } return returnHashMap; } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/PlotState.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/parser/PlotStat0000644000175000017500000001142412533641120031030 0ustar benbenpackage com.baselet.element.elementnew.plot.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; public class PlotState { private final List subPlots; private DataSet dataset; private final HashMap values; private final int plotLineNr; protected PlotState(int plotLineNr, HashMap values) { subPlots = new ArrayList(); this.plotLineNr = plotLineNr; this.values = values; } /** * Is only called once by the parser to calculate the dataset. */ protected void setDataSet(DataSet dataset) { this.dataset = dataset; } public void addSubPlot(PlotState plotState) { subPlots.add(plotState); } public List getSubplots() { return subPlots; } public DataSet getDataSet() { return dataset; } public boolean containsKey(String key) { return values.containsKey(key); } public int getLine(String key) { if (values.get(key) != null) { return values.get(key).getLine(); } else { return -1; } } public int getPlotLineNr() { return plotLineNr; } public String getValue(String key, String defaultValue) { KeyValue keyValue = values.get(key); if (keyValue != null) { keyValue.setUsed(true); } if (keyValue == null || keyValue.getValue().equals(PlotConstants.DEFAULT_VALUE)) { return defaultValue; } else { return keyValue.getValue(); } } public String getValueValidated(String key, String defaultValue, List validValues) { String value = getValue(key, defaultValue); if (!validValues.contains(value)) { throw new ParserException(key, value, getLine(key)); } return value; } public Double getValueAsDouble(String key, Double defaultValue) { try { String value = getValue(key, null); if (value == null) { return defaultValue; } else { return Double.parseDouble(value); } } catch (Exception e) { throw new ParserException(key, values.get(key).getValue(), values.get(key).getLine()); } } public Integer getValueAsInt(String key, Integer defaultValue) { try { String value = getValue(key, null); if (value == null) { return defaultValue; } else { return Integer.parseInt(value); } } catch (Exception e) { throw new ParserException(key, values.get(key).getValue(), values.get(key).getLine()); } } public Boolean getValueAsBoolean(String key, Boolean defaultValue) { String value = getValue(key, null); if (value == null) { return defaultValue; } else if (value.equals("true")) { return true; } else if (value.equals("false")) { return false; } else { throw new ParserException(key, values.get(key).getValue(), values.get(key).getLine()); } } public List getValueList(String key, List defaultValue) { List returnArray; String value = getValue(key, null); if (value == null) { returnArray = defaultValue; } else { returnArray = Arrays.asList(value.split(PlotConstants.VALUE_LIST_SEPARATOR)); } return returnArray; } public List getValueListValidated(String key, List defaultValue, List validValues, boolean doubleValuesAllowed) { List valueList = getValueList(key, defaultValue); for (String value : valueList) { boolean intAllowedAndValueIsInt = doubleValuesAllowed && isDoubleValue(value); if (!validValues.contains(value) && !intAllowedAndValueIsInt) { throw new ParserException(key, value, getLine(key)); } } return valueList; } private boolean isDoubleValue(String value) { try { Double.parseDouble(value); return true; } catch (Exception e) { return false; } } /** * Checks if all declared values are used. It throws an error for declarations which are not used by the plot (=they are invalid) */ public void checkIfAllValuesUsed() { StringBuilder sb = new StringBuilder(""); for (KeyValue keyValue : values.values()) { if (!keyValue.isUsed()) { sb.append("\"").append(keyValue.getKey()).append("=").append(keyValue.getValue()).append("\" (line ").append(keyValue.getLine()).append(") "); } } String unusedVariables = sb.toString(); if (!unusedVariables.isEmpty()) { throw new ParserException("Invalid variables: " + unusedVariables); } } @Override public String toString() { StringBuilder sb = new StringBuilder(""); sb.append("PlotState (").append(plotLineNr).append(")\n"); if (dataset != null) { sb.append("\tdataset -> ").append(dataset.getLineNr()).append("\n"); } for (KeyValue keyValue : values.values()) { sb.append("\t").append(keyValue).append("\n"); } if (!subPlots.isEmpty()) { sb.append("---Begin Subplots---\n"); for (PlotState subPlot : subPlots) { sb.append(subPlot.toString()); } sb.append("---End Subplots---\n"); } return sb.toString(); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/0000755000175000017500000000000012533641120027651 5ustar benben././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/PiePlot.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/PiePlo0000644000175000017500000000227312533641120030770 0ustar benbenpackage com.baselet.element.elementnew.plot.elements; import java.util.Arrays; import java.util.List; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; import com.baselet.element.elementnew.plot.parser.PlotState; public class PiePlot extends AbstractPlot { public PiePlot(DrawHandler drawer, PlotGridDrawConfig plotDrawConfig, PlotState plotState, int xPos, int yPos) { super(drawer, plotDrawConfig, plotState, xPos, yPos); } @Override public void plot(int columnCount, int rowCount) { setPlotPosition(columnCount, rowCount); plotState.checkIfAllValuesUsed(); plot.drawPiePlot(); } @Override protected List defaultDescAxisShow() { return Arrays.asList(); } @Override protected List defaultValueAxisShow() { return defaultDescAxisShow(); } @Override protected List defaultValueAxisList() { return Arrays.asList(); } @Override protected int getMaxAllowedValueRows() { return 1; } } ././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/AbstractPlot.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/Abstra0000644000175000017500000001224112533641120031010 0ustar benbenpackage com.baselet.element.elementnew.plot.elements; import java.util.List; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.elementnew.plot.drawer.AxisConfig; import com.baselet.element.elementnew.plot.drawer.PlotDrawHandler; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.parser.DataSet; import com.baselet.element.elementnew.plot.parser.ParserException; import com.baselet.element.elementnew.plot.parser.PlotConstants; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; import com.baselet.element.elementnew.plot.parser.PlotState; public abstract class AbstractPlot { protected PlotDrawHandler plot; protected PlotGridDrawConfig plotDrawConfig; protected PlotState plotState; private final Integer xPosition; private final Integer yPosition; public AbstractPlot(DrawHandler drawer, PlotGridDrawConfig plotDrawConfig, PlotState plotState, int xPosition, int yPosition) { this.plotDrawConfig = plotDrawConfig; this.plotState = plotState; this.xPosition = xPosition; this.yPosition = yPosition; plot = new PlotDrawHandler(drawer, plotDrawConfig.getRealSize()); setupAxis(); setupAbstractPlot(); } public Integer getPlotLineNr() { return plotState.getPlotLineNr(); } public Integer getXPosition() { return xPosition; } public Integer getYPosition() { return yPosition; } private void setupAxis() { plot.getAxisConfig().enableDescAxis( plotState.getValueListValidated(AxisShow.getKeyDescAxis(), PlotConstants.toStringList(defaultDescAxisShow()), PlotConstants.toStringList(AxisShow.values()), false)); plot.getAxisConfig().enableValueAxis( plotState.getValueListValidated(AxisShow.getKeyValueAxis(), PlotConstants.toStringList(defaultValueAxisShow()), PlotConstants.toStringList(AxisShow.values()), false), plotState.getValueListValidated(AxisList.getKey(), PlotConstants.toStringList(defaultValueAxisList()), PlotConstants.toStringList(AxisList.values()), true)); } private void setupAbstractPlot() { DataSet ds = plotState.getDataSet(); ds.setInvert(plotState.getValueAsBoolean(PlotConstants.KEY_BOOL_DATA_INVERT, PlotConstants.DATA_INVERT_DEFAULT)); String[] desc = ds.titleRow(); String[] title = ds.titleCol(); // System.out.print("\ntitle of ds " + ds.getLineNr() + " :"); // for (String t : title) System.out.print("<" + t + ">"); Double[][] values = ds.data(); List colors = plotState.getValueList(PlotConstants.KEY_LIST_COLORS, PlotConstants.COLORS_DEFAULT); for (String color : colors) { if (ColorOwn.forStringOrNull(color, Transparency.FOREGROUND) == null) { throw new ParserException("Unknown color: " + color + "(line: " + plotState.getLine(PlotConstants.KEY_LIST_COLORS) + ")"); } } if (values.length > getMaxAllowedValueRows()) { throw new ParserException("The dataset (line: " + plotState.getDataSet().getLineNr() + ") has too many rows for the plot (line: " + plotState.getPlotLineNr() + ")"); } plot.setValues(desc, title, values, colors); setMinMaxValue(PlotConstants.KEY_INT_MIN_VALUE); setMinMaxValue(PlotConstants.KEY_INT_MAX_VALUE); } private void setMinMaxValue(String key) { String stringValue = plotState.getValue(key, null); if (stringValue != null) { try { if (key.equals(PlotConstants.KEY_INT_MIN_VALUE)) { if (stringValue.equals(PlotConstants.MIN_VALUE_ALL)) { plot.setMinValue(plotDrawConfig.getMinValue()); } else { plot.setMinValue(Double.valueOf(stringValue)); } } else if (key.equals(PlotConstants.KEY_INT_MAX_VALUE)) { if (stringValue.equals(PlotConstants.MAX_VALUE_ALL)) { plot.setMaxValue(plotDrawConfig.getMaxValue()); } else { plot.setMaxValue(Double.valueOf(stringValue)); } } } catch (Exception e) { throw new ParserException(key, stringValue, plotState.getLine(key), e.getMessage()); } } } protected void setPlotPosition(int columnCount, int rowCount) { if (xPosition > columnCount) { throw new ParserException("The x coordinate is invalid. PlotGrid width is too small"); } if (yPosition > rowCount) { throw new ParserException("The y coordinate is invalid. PlotGrid height is too small"); } double segmentWidth = (double) plotDrawConfig.getRealSize().width / columnCount; double segmentHeight = (double) plotDrawConfig.getRealSize().height / rowCount; int spaceLeft = (int) (segmentWidth * xPosition); int spaceRight = (int) (segmentWidth * (columnCount - xPosition - 1)); int spaceTop = (int) (segmentHeight * yPosition); int spaceBottom = (int) (segmentHeight * (rowCount - yPosition - 1)); plot.getCanvas().setBorder(spaceLeft, spaceTop, spaceRight, spaceBottom, AxisConfig.ARROW_DISTANCE); } public abstract void plot(int columnCount, int rowCount); protected abstract List defaultDescAxisShow(); protected abstract List defaultValueAxisShow(); protected abstract List defaultValueAxisList(); protected abstract int getMaxAllowedValueRows(); } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/LinePlot.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/LinePl0000644000175000017500000000276412533641120030770 0ustar benbenpackage com.baselet.element.elementnew.plot.elements; import java.util.Arrays; import java.util.List; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.parser.PlotConstants; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; import com.baselet.element.elementnew.plot.parser.PlotState; public class LinePlot extends AbstractPlot { public LinePlot(DrawHandler drawer, PlotGridDrawConfig plotDrawConfig, PlotState plotState, int xPos, int yPos) { super(drawer, plotDrawConfig, plotState, xPos, yPos); } @Override public void plot(int columnCount, int rowCount) { setPlotPosition(columnCount, rowCount); Boolean tilt = plotState.getValueAsBoolean(PlotConstants.KEY_BOOL_PLOT_TILT, PlotConstants.PLOT_TILT_DEFAULT); plotState.checkIfAllValuesUsed(); plot.drawPlotAndDescValueAxis(!tilt, false, true, false); } @Override protected List defaultDescAxisShow() { return Arrays.asList(AxisShow.Axis, AxisShow.Line, AxisShow.Marker, AxisShow.Text); } @Override protected List defaultValueAxisShow() { return defaultDescAxisShow(); } @Override protected List defaultValueAxisList() { return Arrays.asList(AxisList.Relevant); } @Override protected int getMaxAllowedValueRows() { return Integer.MAX_VALUE; } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/BarPlot.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/BarPlo0000644000175000017500000000357612533641120030766 0ustar benbenpackage com.baselet.element.elementnew.plot.elements; import java.io.IOException; import java.util.Arrays; import java.util.List; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.parser.PlotConstants; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; import com.baselet.element.elementnew.plot.parser.PlotState; public class BarPlot extends AbstractPlot { public BarPlot(DrawHandler drawer, PlotGridDrawConfig plotDrawConfig, PlotState plotState, int xPos, int yPos) { super(drawer, plotDrawConfig, plotState, xPos, yPos); } @Override public void plot(int columnCount, int rowCount) { setPlotPosition(columnCount, rowCount); // The barplot should always start at 0 even if there are only values which are > 0 or only values < 0 try { if (!plotState.containsKey(PlotConstants.KEY_INT_MIN_VALUE)) { plot.setMinValue(0.0); } } catch (IOException e) {} try { if (!plotState.containsKey(PlotConstants.KEY_INT_MAX_VALUE)) { plot.setMaxValue(0.0); } } catch (IOException e) {} Boolean tilt = plotState.getValueAsBoolean(PlotConstants.KEY_BOOL_PLOT_TILT, PlotConstants.PLOT_TILT_DEFAULT); plotState.checkIfAllValuesUsed(); plot.drawPlotAndDescValueAxis(!tilt, true, false, false); } @Override protected List defaultDescAxisShow() { return Arrays.asList(AxisShow.Axis, AxisShow.Marker, AxisShow.Text); } @Override protected List defaultValueAxisShow() { return Arrays.asList(AxisShow.Axis, AxisShow.Line, AxisShow.Marker, AxisShow.Text); } @Override protected List defaultValueAxisList() { return Arrays.asList(AxisList.Relevant); } @Override protected int getMaxAllowedValueRows() { return Integer.MAX_VALUE; } } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/ScatterPlot.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/elements/Scatte0000644000175000017500000000275312533641120031026 0ustar benbenpackage com.baselet.element.elementnew.plot.elements; import java.util.Arrays; import java.util.List; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.parser.PlotConstants; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; import com.baselet.element.elementnew.plot.parser.PlotState; public class ScatterPlot extends AbstractPlot { public ScatterPlot(DrawHandler drawer, PlotGridDrawConfig plotDrawConfig, PlotState plotState, int xPos, int yPos) { super(drawer, plotDrawConfig, plotState, xPos, yPos); } @Override public void plot(int columnCount, int rowCount) { setPlotPosition(columnCount, rowCount); Boolean tilt = plotState.getValueAsBoolean(PlotConstants.KEY_BOOL_PLOT_TILT, PlotConstants.PLOT_TILT_DEFAULT); plotState.checkIfAllValuesUsed(); plot.drawPlotAndDescValueAxis(!tilt, false, false, true); } @Override protected List defaultDescAxisShow() { return Arrays.asList(AxisShow.Axis, AxisShow.Marker, AxisShow.Text); } @Override protected List defaultValueAxisShow() { return defaultDescAxisShow(); } @Override protected List defaultValueAxisList() { return Arrays.asList(AxisList.Relevant); } @Override protected int getMaxAllowedValueRows() { return Integer.MAX_VALUE; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/0000755000175000017500000000000012533641120027321 5ustar benben././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/PlotGridDrawConfig.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/PlotGrid0000644000175000017500000000134012533641120030766 0ustar benbenpackage com.baselet.element.elementnew.plot.drawer; import com.baselet.control.basics.geom.Dimension; public class PlotGridDrawConfig { private final Dimension realSize; private final Dimension size; private final Double minValue; private final Double maxValue; public PlotGridDrawConfig(Dimension realSize, Dimension size, Double minValue, Double maxValue) { super(); this.realSize = realSize; this.size = size; this.minValue = minValue; this.maxValue = maxValue; } public Dimension getRealSize() { return realSize; } public Dimension getSize() { return size; } public Double getMinValue() { return minValue; } public Double getMaxValue() { return maxValue; } }././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/AxisConfig.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/AxisConf0000644000175000017500000001072012533641120030756 0ustar benbenpackage com.baselet.element.elementnew.plot.drawer; import java.util.List; import java.util.TreeSet; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisList; import com.baselet.element.elementnew.plot.parser.PlotConstants.AxisShow; public class AxisConfig { private boolean descAxisLine, valueAxisLine; private boolean descAxisMarkers, valueAxisMarkers; private boolean descAxisText, valueAxisText; private boolean descAxisGray, valueAxisGray; private TreeSet valueAxisList; private boolean showRelevantValues; public static final int ARROW_SIZE = (int) (5 * 1f); // arrowLength * arrowEndAngle public static final int ARROW_DISTANCE = ARROW_SIZE * 3; // Distance between outerBorder and innerBorder; plotarea where only axis are allowed to draw private boolean xIsDescription; private boolean drawAxis; private int descSegment; // The width of a bar (always the "shorter" side of the bar) private Double valueSegment; // How many pixels equal one valuesegment (eg: if values reach from 1 to 100000 it's very small, if they reach from 1 to 5 it's very high) private int descAxisPos; // If horizontal sourceAxisPos is the x value of the vertical axis, else it's the y value of the horizontal axis private int valueAxisPos; // If horizontal sourceAxisPos is the x value of the vertical axis, else it's the y value of the horizontal axis private int xAxisPos; private int yAxisPos; public AxisConfig() { super(); drawAxis = false; } public final void enableDescAxis(List showList/* , List valueList */) { drawAxis = true; descAxisLine = showList.contains(AxisShow.Axis.getValue()); descAxisGray = showList.contains(AxisShow.Line.getValue()); descAxisMarkers = showList.contains(AxisShow.Marker.getValue()); descAxisText = showList.contains(AxisShow.Text.getValue()); } public final void enableValueAxis(List showList, List valueList) { drawAxis = true; valueAxisLine = showList.contains(AxisShow.Axis.getValue()); valueAxisGray = showList.contains(AxisShow.Line.getValue()); valueAxisMarkers = showList.contains(AxisShow.Marker.getValue()); valueAxisText = showList.contains(AxisShow.Text.getValue()); showRelevantValues = valueList.contains(AxisList.Relevant.getValue()); valueAxisList = new TreeSet(); for (String v : valueList) { try { valueAxisList.add(Double.parseDouble(v)); } catch (Exception e) {} } } public boolean isxDescription() { return xIsDescription; } public void setxIsDescription(boolean xIsDescription) { this.xIsDescription = xIsDescription; } public boolean showAxis() { return drawAxis; } public boolean drawXAxis() { return isxDescription() && descAxisLine || !isxDescription() && valueAxisLine; } public boolean drawYAxis() { return isxDescription() && valueAxisLine || !isxDescription() && descAxisLine; } public boolean drawDescriptionAxisMarkers() { return descAxisMarkers; } public boolean drawDescriptionAxisMarkerText() { return descAxisText; } public boolean drawDescriptionAxisMarkerGrayline() { return descAxisGray; } public boolean drawValueAxis() { return valueAxisLine; } public boolean drawValueAxisMarkers() { return valueAxisMarkers; } public boolean drawValueAxisMarkerText() { return valueAxisText; } public boolean drawValueAxisMarkerGrayline() { return valueAxisGray; } public void setDescAxisPos(int pos) { descAxisPos = pos; if (xIsDescription) { xAxisPos = pos; } else { yAxisPos = pos; } } public int getxAxisPos() { return xAxisPos; } public void setValueAxisPos(int pos) { valueAxisPos = pos; if (!xIsDescription) { xAxisPos = pos; } else { yAxisPos = pos; } } public int getyAxisPos() { return yAxisPos; } public int getDescAxisPos() { return descAxisPos; } public int getValueAxisPos() { return valueAxisPos; } public int getDescSegment() { return descSegment; } public void setDescSegment(int descSegment) { this.descSegment = descSegment; } public Double getValueSegment() { return valueSegment; } public void setValueSegment(Double valueSegment) { this.valueSegment = valueSegment; } public TreeSet setValueAxisList(TreeSet valuesSorted) { if (showRelevantValues) { valueAxisList.addAll(valuesSorted); } return valueAxisList; } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/Canvas.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/Canvas.j0000644000175000017500000001172412533641120030714 0ustar benbenpackage com.baselet.element.elementnew.plot.drawer; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; /** * GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG * G G * G OOOOOOOOOOOOOOO G * G O O G * G O IIIIIIIII O G * G O I I O G * G O I I O G * G O IIIIIIIII O G * G O O G * G OOOOOOOOOOOOOOO G * G G * G G * G G * G G * G G * G G * GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG */ public class Canvas { private int borderspace; private Rectangle outerBorder; // Nothing is drawn between outerBorder and the GridElement-Border private Rectangle innerBorder; // Only axis are drawn between outerBorder and innerBorder; inside the innerBorder the plot is drawn private Dimension gridElementSize; public Canvas(Dimension gridElementSize) { super(); this.gridElementSize = gridElementSize; outerBorder = new Rectangle(); innerBorder = new Rectangle(); setBorder(0, 0, 0, 0, 0); } public void setBorder(int x, int y, int width, int height, int borderspace) { this.borderspace = borderspace; outerBorder.setBounds(x, y, width, height); updateInnerBorder(); } public void setBorderX(int x) { outerBorder.setBounds(x, outerBorder.y, outerBorder.width, outerBorder.height); updateInnerBorder(); } public void setBorderY(int y) { outerBorder.setBounds(outerBorder.x, y, outerBorder.width, outerBorder.height); updateInnerBorder(); } public void setBorderWidth(int width) { outerBorder.setBounds(outerBorder.x, outerBorder.y, width, outerBorder.height); updateInnerBorder(); } public void setBorderHeight(int height) { outerBorder.setBounds(outerBorder.x, outerBorder.y, outerBorder.width, height); updateInnerBorder(); } private void updateInnerBorder() { innerBorder.setBounds(outerBorder.x + borderspace, outerBorder.y + borderspace, outerBorder.width + borderspace, outerBorder.height + borderspace); } /** * <-----> * G O I I O G */ public int getInnerLeftPos() { return innerBorder.x; } public int getInnerUpPos() { return innerBorder.y; } /** * <------------------> * G O I I O G */ public int getInnerRightBorderWidth() { return innerBorder.width; } public int getInnerDownBorderHeight() { return innerBorder.height; } /** * <-------------> * G O I I O G */ public int getInnerRightPos() { return gridElementSize.width - getInnerRightBorderWidth(); } public int getInnerDownPos() { return gridElementSize.height - getInnerDownBorderHeight(); } /** * <-----> <------------------> * G O I I O G */ public int getInnerHorizontalSum() { return getInnerLeftPos() + getInnerRightBorderWidth(); } public int getInnerVerticalSum() { return getInnerUpPos() + getInnerDownBorderHeight(); } /** * <-------> * G O I I O G */ public int getInnerHorizontalDrawspace() { return getInnerRightPos() - getInnerLeftPos(); } public int getInnerVerticalDrawspace() { return getInnerDownPos() - getInnerUpPos(); } public int getOuterLeftPos() { return outerBorder.x; } public int getOuterUpPos() { return outerBorder.y; } public int getOuterRightBorderWidth() { return outerBorder.width; } public int getOuterDownBorderHeight() { return outerBorder.height; } public int getOuterRightPos() { return gridElementSize.width - getOuterRightBorderWidth(); } public int getOuterDownPos() { return gridElementSize.height - getOuterDownBorderHeight(); } public int getOuterHorizontalSum() { return getOuterLeftPos() + getOuterRightBorderWidth(); } public int getOuterVerticalSum() { return getOuterUpPos() + getOuterDownBorderHeight(); } public boolean hasHorizontalDrawspace() { return gridElementSize.width > getOuterHorizontalSum(); } public boolean hasVerticalDrawspace() { return gridElementSize.width > getOuterHorizontalSum(); } public void draw(DrawHandler baseDrawHandler) { baseDrawHandler.setBackgroundColor(ColorOwn.TRANSPARENT); baseDrawHandler.setForegroundColor(ColorOwn.RED.transparency(Transparency.BACKGROUND)); baseDrawHandler.drawRectangle(getOuterLeftPos(), getOuterUpPos(), getOuterRightPos() - getOuterLeftPos() - 1, getOuterDownPos() - getOuterUpPos()); baseDrawHandler.setForegroundColor(ColorOwn.BLUE); baseDrawHandler.drawRectangle(getInnerLeftPos(), getInnerUpPos(), getInnerRightPos() - getInnerLeftPos(), getInnerDownPos() - getInnerUpPos()); } } ././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/PlotDrawHandler.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/drawer/PlotDraw0000644000175000017500000005612612533641120031012 0ustar benbenpackage com.baselet.element.elementnew.plot.drawer; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.TreeSet; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Point; import com.baselet.control.enums.AlignHorizontal; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; public class PlotDrawHandler { // Enumerations public enum Position { LEFT, UP, DOWN, RIGHT } // Plot specific settings private String[] title; private String[] desc; private Double[][] values; private TreeSet valuesSorted; private TreeSet valuesShownOnAxisSorted; // private Double[][] valuesMinMaxCorrected; // if all values are >0 or all values are <0 the distance from 0 to the first real value will be subtracted protected DrawHandler base; private Double minVal = null; private Double maxVal = null; private List colors; private final Canvas canvas; private final AxisConfig axisConfig; public PlotDrawHandler(DrawHandler baseDrawHandler, Dimension size) { base = baseDrawHandler; // drawLegend = false; axisConfig = new AxisConfig(); canvas = new Canvas(size); } // Legend Settings // private boolean drawLegend; // private Rectangle legendPos; // /** // * Abstracts the axis drawing from the type of variables on the axis (description or values) // * Methods called from this method don't know if they handle a description or value axis // * @param xAxis if true this is the method call for the x-axis // * @param valuesSorted the sorted list of values // */ // private void abstractValueDescFromAxisAndDraw(boolean xAxis) { // int segmentDisp, lastDrawnSegmentDisp; // // if /* thisIsDescAxis */ ((xAxis && axisConfig.isxDescription()) || (!xAxis && !axisConfig.isxDescription())) { // // if (axisConfig.drawDescriptionAxis()) drawAxisLine(xAxis); // if (true) { // lastDrawnSegmentDisp = -axisConfig.getDescSegment()/2; // for (int i = 0; i < desc.length; i++) { // segmentDisp = (i * axisConfig.getDescSegment()) + (axisConfig.getDescSegment()/2); // String value; // if (xAxis) value = desc[i]; // else value = desc[desc.length-i-1]; // yAxis is drawn from bottom to top, therefore invert computation direction // // axisConfig.activateDescriptionAxis(); // lastDrawnSegmentDisp = drawMarkerTextIfThereIsEnoughSpace(xAxis, segmentDisp, lastDrawnSegmentDisp, value); // } // } // } // else /* thisIsValueAxis */ { // // if (axisConfig.drawValueAxis()) drawAxisLine(xAxis); // if (true) { // Double[] valuesToDisplay; // if (axisConfig.drawValueAxisMarkersAll()) { // if (axisConfig.getValueSegment() < 1) valuesToDisplay = Utils.createDoubleArrayFromTo(minVal, maxVal, Math.ceil(1/axisConfig.getValueSegment())); // else valuesToDisplay = Utils.createDoubleArrayFromTo(minVal, maxVal); // } // else valuesToDisplay = valuesSorted; // // lastDrawnSegmentDisp = (int) (valuesToDisplay[0] * axisConfig.getValueSegment() - 100); // Start at the lowest possible number // for (Double v : valuesToDisplay) { // segmentDisp = (int) calculateValuePos(v, axisConfig.getValueSegment()); // // valueStringToDisplay is the String representation of the value (".0" should not be displayed) // String valueStringToDisplay = (Math.round(v) == v) ? String.valueOf(Math.round(v)) : String.valueOf(v); // if (axisConfig.drawValueAxisMarkersAll()) { // int oldLength = valueStringToDisplay.length(); // if (oldLength > 2) { // valueStringToDisplay = valueStringToDisplay.substring(0, 2); // for (int i = 0; i < oldLength-2; i++) valueStringToDisplay += "0"; // } // } // // if (value == 0) continue; // 0 is not displayed because it would overlap with the arrow end // // axisConfig.activateValueAxis(); // lastDrawnSegmentDisp = drawMarkerTextIfThereIsEnoughSpace(xAxis, segmentDisp, lastDrawnSegmentDisp, valueStringToDisplay); // } // } // } // } // // /** // * Draws text descriptions of axes only if there is enough space for it. // */ // private int drawMarkerTextIfThereIsEnoughSpace(boolean xAxis, int segmentDisp, int lastDrawnSegmentDisp, String valueAsString) { // boolean drawMarker = false; // // If text should be displayed markers where there would be no space for the text are not drawn // // if (axisConfig.drawActiveAxisMarkerText()) { // int textSpaceNeeded; // if (xAxis) textSpaceNeeded = base.textWidth(valueAsString); // else textSpaceNeeded = base.textHeight(); // if ((segmentDisp - lastDrawnSegmentDisp) >= textSpaceNeeded) { // drawMarker = true; // lastDrawnSegmentDisp = segmentDisp; // } // // } // else drawMarker = true; // // if (drawMarker) drawAxisMarker(xAxis, segmentDisp, valueAsString); // return lastDrawnSegmentDisp; // } // //TODO isnt working properly now // public void enableLegend(Position position) { // this.drawLegend = true; // this.legendPos = getLegendPosition(position); // } // // public void disableLegend() { // this.drawLegend = false; // } // // private void drawLegend() { // base.drawRectangle(legendPos.x, legendPos.y, legendPos.width, legendPos.height); // } // // private Rectangle getLegendPosition(Position position) { // // Calculate size of the legend // final Rectangle innerLegendBorder = new Rectangle(10, 10, 10, 10); // int legendWidth = innerLegendBorder.x + innerLegendBorder.width; // int legendHeight = innerLegendBorder.y + innerLegendBorder.height; // final int legendSpace = 10; // // int textWidth; // for (String v : desc) { // legendHeight += base.textHeight(); // textWidth = base.textWidth(v) + innerLegendBorder.x + innerLegendBorder.width; // if (textWidth > legendWidth) legendWidth = textWidth; // } // // // The outerBorder of the plot must be adjusted to free space for the legend // int borderX = canvas.getOuterLeftPos(); // int borderY = canvas.getOuterUpPos(); // int borderW = canvas.getOuterRightBorderWidth(); // int borderH = canvas.getOuterDownBorderHeight(); // // if (position == Position.LEFT) borderX += legendWidth + legendSpace; // else if (position == Position.RIGHT) borderW += legendWidth + legendSpace; // else if (position == Position.UP) borderY += legendHeight + legendSpace; // else if (position == Position.DOWN) borderH += legendHeight + legendSpace; // // canvas.setBorder(borderX, borderY, borderW, borderH, AxisConfig.ARROW_DISTANCE); // // // Calculate and return the position of the legend rectangle // final int x, y; // if (position == Position.LEFT || position == Position.RIGHT) { // y = (canvas.getInnerDownPos() - legendHeight) / 2; // if (position == Position.LEFT) { // x = 1; // } else { // x = canvas.getInnerRightPos() - legendWidth - legendSpace/2; // } // } else { // x = (canvas.getInnerRightPos() - legendWidth) / 2; // if (position == Position.UP) { // y = 1; // } else { // y = canvas.getInnerDownPos() - legendHeight - legendSpace/2; // } // } // return new Rectangle(x, y, legendWidth, legendHeight); // } public final void drawPlotAndDescValueAxis(boolean xIsDescription, boolean drawBars, boolean drawLines, boolean drawPoints) { axisConfig.setxIsDescription(xIsDescription); setupAxis(); calculateAdditionalSpaceForYAxisTextWidth(); // log.debug("yIsDescription: " + yIsDescription + ", descSegment: " + axisConfig.getDescSegment() + ", valueSegment: " + axisConfig.getValueSegment()); // log.debug("valueRange: " + valueRange + ", barsCount: " + elementCount + ", SourceAxisPos/DescAxisPos: " + axisConfig.getDescAxisPos() + ", BarStart/ValueAxisPos: " + axisConfig.getValueAxisPos()); if (drawBars) { drawBars(xIsDescription, values, axisConfig.getDescAxisPos(), axisConfig.getValueAxisPos(), axisConfig.getValueSegment(), axisConfig.getDescSegment(), colors); } if (drawLines) { drawLineOrPoints(xIsDescription, values, axisConfig.getDescAxisPos(), axisConfig.getValueAxisPos(), axisConfig.getValueSegment(), axisConfig.getDescSegment(), colors, true); } if (drawPoints) { drawLineOrPoints(xIsDescription, values, axisConfig.getDescAxisPos(), axisConfig.getValueAxisPos(), axisConfig.getValueSegment(), axisConfig.getDescSegment(), colors, false); } if (axisConfig.showAxis()) { drawAxis(xIsDescription, axisConfig.getDescAxisPos(), axisConfig.getValueAxisPos(), axisConfig.getValueSegment(), axisConfig.getDescSegment()); } } private void setupAxis() { final Double valueRange = Math.max(1.0, maxVal - minVal); // The range is >=1 (otherwise nothing will be drawn) Double negativeRange = 0.0; if (minVal > 0) { negativeRange = 0.0; } if (minVal < 0) { if (maxVal < 0) { negativeRange = valueRange; } else { negativeRange = -minVal; } } int elementCount = desc.length; // Amount of bars/lines/... for (Double[] vArray : values) { if (vArray.length > elementCount) { elementCount = vArray.length; } } // Calculate some necessary variables to draw the bars (these variables abstract from horizontal/vertical to a relative point of view) if (axisConfig.isxDescription()) { axisConfig.setDescSegment(canvas.getInnerHorizontalDrawspace() / elementCount); axisConfig.setValueSegment(canvas.getInnerVerticalDrawspace() / valueRange); axisConfig.setDescAxisPos((int) (canvas.getInnerDownPos() - axisConfig.getValueSegment() * negativeRange)); axisConfig.setValueAxisPos(canvas.getInnerLeftPos()); } else { axisConfig.setDescSegment(canvas.getInnerVerticalDrawspace() / elementCount); axisConfig.setValueSegment(canvas.getInnerHorizontalDrawspace() / valueRange); axisConfig.setDescAxisPos((int) (canvas.getInnerLeftPos() + axisConfig.getValueSegment() * negativeRange)); axisConfig.setValueAxisPos(canvas.getInnerUpPos()); } } private final void drawAxis(boolean xIsDescription, int sourceAxisPos, int valueAxisPos, Double valueSegment, int descSegment) { List xpoints = new ArrayList(); List xtext = new ArrayList(); List ypoints = new ArrayList(); List ytext = new ArrayList(); int lineIterator = valueAxisPos + descSegment / 2; for (String d : desc) { if (xIsDescription) { xpoints.add(lineIterator); xtext.add(d); } else { ypoints.add(lineIterator); ytext.add(d); } lineIterator += descSegment; } for (Double v : valuesShownOnAxisSorted) { int linePos = (int) calculateValuePos(v, valueSegment); if (xIsDescription) { ypoints.add(sourceAxisPos - linePos); ytext.add(String.valueOf(v)); } else { xpoints.add(sourceAxisPos + linePos); xtext.add(String.valueOf(v)); } } drawGraylines(xpoints, ypoints); base.setForegroundColor(ColorOwn.BLACK.transparency(Transparency.FOREGROUND)); drawAxisLine(); drawMarkers(xpoints, ypoints); drawMarkerTexts(xpoints, xtext, ypoints, ytext); } /** * Method to draw one line (which one is specified by the boolean xAxis variable) * @param xAxis * @param drawArrows */ private void drawAxisLine() { if (axisConfig.drawXAxis()) { final int x1 = canvas.getInnerLeftPos(); final int x2 = canvas.getInnerRightPos(); final int y = axisConfig.getxAxisPos(); base.drawLine(x1, y, x2, y); } if (axisConfig.drawYAxis()) { final int x = axisConfig.getyAxisPos(); final int y1 = canvas.getInnerUpPos(); final int y2 = canvas.getInnerDownPos(); base.drawLine(x, y1, x, y2); } } private void drawGraylines(List xpoints, List ypoints) { base.setForegroundColor(ColorOwn.BLACK.transparency(Transparency.SELECTION_BACKGROUND)); boolean drawVerticalGraylines = axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkerGrayline() || !axisConfig.isxDescription() && axisConfig.drawValueAxisMarkerGrayline(); boolean drawHorizontalGraylines = !axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkerGrayline() || axisConfig.isxDescription() && axisConfig.drawValueAxisMarkerGrayline(); if (drawVerticalGraylines) { for (Integer x : xpoints) { base.drawLine(x, canvas.getInnerUpPos(), x, canvas.getInnerDownPos()); } } if (drawHorizontalGraylines) { for (Integer y : ypoints) { base.drawLine(canvas.getInnerLeftPos(), y, canvas.getInnerRightPos(), y); } } } private void drawMarkers(List xpoints, List ypoints) { boolean drawVerticalMarkers = axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkers() || !axisConfig.isxDescription() && axisConfig.drawValueAxisMarkers(); boolean drawHorizontalMarkers = !axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkers() || axisConfig.isxDescription() && axisConfig.drawValueAxisMarkers(); if (drawVerticalMarkers) { for (Integer x : xpoints) { base.drawLine(x, axisConfig.getxAxisPos(), x, axisConfig.getxAxisPos() + AxisConfig.ARROW_SIZE); } } if (drawHorizontalMarkers) { for (Integer y : ypoints) { base.drawLine(axisConfig.getyAxisPos() - AxisConfig.ARROW_SIZE, y, axisConfig.getyAxisPos(), y); } } } private void drawMarkerTexts(List xpoints, List xtext, List ypoints, List ytext) { boolean drawVerticalMarkerTexts = axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkerText() || !axisConfig.isxDescription() && axisConfig.drawValueAxisMarkerText(); boolean drawHorizontalMarkerTexts = !axisConfig.isxDescription() && axisConfig.drawDescriptionAxisMarkerText() || axisConfig.isxDescription() && axisConfig.drawValueAxisMarkerText(); if (drawVerticalMarkerTexts) { for (int i = 0; i < xpoints.size(); i++) { base.print(xtext.get(i), xpoints.get(i), axisConfig.getxAxisPos() + AxisConfig.ARROW_DISTANCE, AlignHorizontal.CENTER); } } if (drawHorizontalMarkerTexts) { for (int i = 0; i < ypoints.size(); i++) { base.print(ytext.get(i), axisConfig.getyAxisPos() - 8, (int) (ypoints.get(i) + base.textHeightMax() / 2), AlignHorizontal.RIGHT); } } } private final void drawLineOrPoints(boolean xIsDescription, Double[][] values, int sourceAxisPos, int valueAxisPos, Double valueSegment, int descSegment, List colors, boolean line) { int cIndex = 0; for (int valueIndex = 0; valueIndex < values.length; valueIndex++) { Double[] vArray = values[valueIndex]; int actualValPos; int lineIterator = valueAxisPos + descSegment / 2; List points = new ArrayList(); for (Double v : vArray) { actualValPos = (int) calculateValuePos(v, valueSegment); if (xIsDescription) { points.add(new Point(lineIterator, sourceAxisPos - actualValPos)); } else { points.add(new Point(sourceAxisPos + actualValPos, lineIterator)); } lineIterator += descSegment; } if (cIndex >= colors.size()) { cIndex = 0; // Restart with first color if all colors in the array has been used } base.setForegroundColor(ColorOwn.forStringOrNull(colors.get(cIndex), Transparency.FOREGROUND)); base.setBackgroundColor(ColorOwn.forStringOrNull(colors.get(cIndex), Transparency.FOREGROUND)); if (line) { for (int i = 0; i < points.size() - 1; i++) { Point point1 = points.get(i); Point point2 = points.get(i + 1); base.drawLine(point1.x, point1.y, point2.x, point2.y); } } else { for (int i = 0; i < points.size(); i++) { Point point = points.get(i); base.drawCircle(point.x, point.y, 2); } } // print titleCol base.setForegroundColor(ColorOwn.forStringOrNull(colors.get(cIndex), Transparency.FOREGROUND).darken(75)); base.print(title[valueIndex], points.get(points.size() - 1).x, points.get(points.size() - 1).y, AlignHorizontal.CENTER); cIndex++; } base.resetColorSettings(); } private final void drawBars(boolean xIsDescription, Double[][] values, int sourceAxisPos, int valueAxisPos, Double valueSegment, int descSegment, List colors) { int barLength; int valueRowAmount = values.length; for (int vIndex = 0; vIndex < valueRowAmount; vIndex++) { int cIndex = 0; int subBarIterator = valueAxisPos; for (Double v : values[vIndex]) { if (cIndex >= colors.size()) { cIndex = 0; // Restart with first color if all colors in the array has been used } base.setForegroundColor(ColorOwn.TRANSPARENT); base.setBackgroundColor(colors.get(cIndex)); barLength = (int) calculateValuePos(v, valueSegment); int barWidth = 0; int ownvar = vIndex * (int) Math.round((double) descSegment / valueRowAmount); // calculate last bar width, fixing rounding errors if (vIndex == valueRowAmount - 1) { barWidth = subBarIterator + descSegment - (subBarIterator + ownvar); } else { barWidth = (int) Math.round((double) descSegment / valueRowAmount); } if (xIsDescription) { if (barLength > 0) { base.drawRectangle(subBarIterator + ownvar, sourceAxisPos - barLength, barWidth, barLength); } else { base.drawRectangle(subBarIterator + ownvar, sourceAxisPos, barWidth, -barLength); } } else { if (barLength > 0) { base.drawRectangle(sourceAxisPos, subBarIterator + ownvar, barLength, barWidth); } else { base.drawRectangle(sourceAxisPos + barLength, subBarIterator + ownvar, -barLength, barWidth); } } subBarIterator += descSegment; cIndex++; } } base.resetColorSettings(); } public final void drawPiePlot() { Double valueSum = 0.0; for (Double v : values[0]) { valueSum += Math.abs(v); } final Point ulCorner; final int diameter; int height = canvas.getInnerVerticalDrawspace(); int width = canvas.getInnerHorizontalDrawspace(); diameter = height > width ? width : height; ulCorner = new Point(canvas.getInnerLeftPos(), canvas.getInnerUpPos()); drawPieArcs(values[0], desc, ulCorner, diameter, valueSum, colors); } private final void drawPieArcs(Double[] values, String[] desc, Point ulCorner, int diameter, Double valueSum, List colors) { int cIndex = 0; Double arcAngle = 0D; Double startAngle = 0D; for (int i = 0; i < values.length; i++) { if (cIndex >= colors.size()) { cIndex = 0; // Restart with first color if all colors in the array has been used } ColorOwn currentFg = base.getForegroundColor(); base.setForegroundColor(ColorOwn.TRANSPARENT); base.setBackgroundColor(colors.get(cIndex)); arcAngle = i < values.length - 1 ? Math.round(360.0 / valueSum * Math.abs(values[i])) : 360 - startAngle; // System.out.println("val: "+values[i]+" winkel: "+arcAngle); int height = canvas.getInnerVerticalDrawspace(); int width = canvas.getInnerHorizontalDrawspace(); base.drawArc(ulCorner.x + width / 2.0 - diameter / 2.0, ulCorner.y + height / 2.0 - diameter / 2.0, diameter, diameter, startAngle.floatValue(), arcAngle.floatValue(), false); base.setForegroundColor(currentFg); double radians = (360 - startAngle + (360 - arcAngle / 2)) * Math.PI / 180.0; int value_x = (int) (diameter / 2.0 * Math.cos(radians) + ulCorner.x + diameter / 2.0 + width / 2.0 - diameter / 2.0); int value_y = (int) (diameter / 2.0 * Math.sin(radians) + ulCorner.y + diameter / 2.0 + height / 2.0 - diameter / 2.0); base.setForegroundColor(ColorOwn.forStringOrNull(colors.get(cIndex), Transparency.FOREGROUND).darken(75)); base.print(desc[i], value_x, value_y, AlignHorizontal.CENTER); // System.out.println("value_x: "+value_x+" / value_y:"+value_y); startAngle += arcAngle; cIndex++; } base.resetColorSettings(); } private void calculateAdditionalSpaceForYAxisTextWidth() { double maxWidth = 0; double valueWidth; if (axisConfig.isxDescription()) { // y-axis contains values if (axisConfig.drawValueAxisMarkerText()) { for (Double v : valuesShownOnAxisSorted) { valueWidth = base.textWidth(String.valueOf(v)); if (valueWidth > maxWidth) { maxWidth = valueWidth; } } } } else { // y-axis contains description if (axisConfig.drawDescriptionAxisMarkerText()) { for (String d : desc) { valueWidth = base.textWidth(d); if (valueWidth > maxWidth) { maxWidth = valueWidth; } } } } double adjustValue = maxWidth + canvas.getOuterLeftPos() - (axisConfig.getyAxisPos() - canvas.getInnerLeftPos()) - 5; if (adjustValue > canvas.getOuterLeftPos()) { canvas.setBorderX((int) adjustValue); setupAxis(); // If the y-axis is not exactly over the innerleft-border, it will be displaced by the last setupAxis() call and therefore the additional space for it must be recalculated again if (axisConfig.getyAxisPos() - canvas.getInnerLeftPos() != 0) { adjustValue = maxWidth + canvas.getOuterLeftPos() - (axisConfig.getyAxisPos() - canvas.getInnerLeftPos()) - 5; if (adjustValue > canvas.getOuterLeftPos()) { canvas.setBorderX((int) adjustValue); setupAxis(); } } } } /** * Calculated value * valueSegment but account for displacements of values if all values are positive or negativ (= positive minVal or negative maxVal) */ public double calculateValuePos(double value, double valueSegment) { if (value > 0 && minVal > 0) { value -= minVal; } else if (value < 0 && maxVal < 0) { value -= maxVal; } return value * valueSegment; } public void setValues(String[] desc, String[] title, Double[][] values, List colors) { this.desc = SharedUtils.cloneArray(desc); this.title = SharedUtils.cloneArray(title); this.colors = new ArrayList(colors); this.values = SharedUtils.cloneArray(values); valuesSorted = new TreeSet(); for (Double[] vArray : values) { for (Double v : vArray) { valuesSorted.add(v); } } valuesShownOnAxisSorted = axisConfig.setValueAxisList(valuesSorted); minVal = minRealOrShownValue(); maxVal = maxRealOrShownValue(); } public void setMinValue(Double minVal) throws IOException { Double limit = Math.min(minRealOrShownValue(), maxVal); if (minVal > limit) { throw new IOException("minValue must be <= " + limit); } else { this.minVal = minVal; } } public void setMaxValue(Double maxVal) throws IOException { Double limit = Math.max(maxRealOrShownValue(), minVal); if (maxVal < limit) { throw new IOException("maxValue must be >= " + limit); } else { this.maxVal = maxVal; } } private double minRealOrShownValue() { if (valuesShownOnAxisSorted.isEmpty()) { return valuesSorted.first(); } else { return Math.min(valuesSorted.first(), valuesShownOnAxisSorted.first()); } } private double maxRealOrShownValue() { if (valuesShownOnAxisSorted.isEmpty()) { return valuesSorted.last(); } else { return Math.max(valuesSorted.last(), valuesShownOnAxisSorted.last()); } } public Canvas getCanvas() { return canvas; } public AxisConfig getAxisConfig() { return axisConfig; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/plot/PlotGrid.java0000644000175000017500000002610412533641120030427 0ustar benbenpackage com.baselet.element.elementnew.plot; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.baselet.control.Matrix; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.NewGridElement; import com.baselet.element.elementnew.plot.drawer.PlotGridDrawConfig; import com.baselet.element.elementnew.plot.elements.AbstractPlot; import com.baselet.element.elementnew.plot.elements.BarPlot; import com.baselet.element.elementnew.plot.elements.LinePlot; import com.baselet.element.elementnew.plot.elements.PiePlot; import com.baselet.element.elementnew.plot.elements.ScatterPlot; import com.baselet.element.elementnew.plot.parser.Parser; import com.baselet.element.elementnew.plot.parser.ParserException; import com.baselet.element.elementnew.plot.parser.ParserResult; import com.baselet.element.elementnew.plot.parser.PlotConstants; import com.baselet.element.elementnew.plot.parser.PlotConstants.PlotType; import com.baselet.element.elementnew.plot.parser.PlotState; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsManualresizeCenter; import com.baselet.gui.AutocompletionText; public class PlotGrid extends NewGridElement { private static final Logger log = Logger.getLogger(PlotGrid.class); private Matrix> matrix; private Integer gridWidth; private Double minValue; private Double maxValue; /** * this facet is only here to show autocompletion and include PlotGrid in the new parser logic which uses facets */ public static final Facet PSEUDO_PLOT_FACET = new Facet() { @Override public void handleLine(String line, PropertiesParserState propConfig) { // do nothing } @Override public List getAutocompletionStrings() { return PlotConstants.AUTOCOMPLETION_LIST; } @Override public boolean checkStart(String line, PropertiesParserState propConfig) { return true; } }; private void fillWithPlots(ParserResult parserState) { ArrayList plotStateList = parserState.getPlotStateList(); DrawHandler drawer = parserState.getDrawer(); setOverallMinMaxValue(plotStateList); for (PlotState plotState : plotStateList) { Integer xPos = plotState.getValueAsInt(PlotConstants.KEY_INT_X_POSITION, null); Integer yPos = plotState.getValueAsInt(PlotConstants.KEY_INT_Y_POSITION, null); // 1 is subtracted from the values because the user counts from 1 to x; java counts from 0 to x-1 if (xPos != null) { xPos -= 1; } if (yPos != null) { yPos -= 1; } // case1: x and y are specified if (xPos != null && yPos != null) { setMatrixHeightMinimum(yPos); List> xCoordinateList = matrix.row(yPos); setMinimumListSize(xPos, xCoordinateList); xCoordinateList.set(xPos, createPlots(drawer, plotState, xPos, yPos, "x and y are specified")); } // case2: only x is specified else if (xPos != null) { putPlotInFirstFreeVerticalSpaceOrAddPlot(drawer, xPos, plotState, "only x is specified -> space replaced"); } // case3: only y is specified else if (yPos != null) { setMatrixHeightMinimum(yPos); List> xCoordinateList = matrix.row(yPos); putPlotInFirstFreeHorizontalSpaceOrAddPlot(drawer, xCoordinateList, yPos, plotState, "only y specified -> "); } // case4: no coordinate is specified else { putPlotInFirstFreeMatrixSpace(drawer, plotState); } } gridWidth = matrix.cols(); // Recalculate grid width log.debug("\n" + toString() + "\n"); } private void setOverallMinMaxValue(List plotStateList) { minValue = Double.MAX_VALUE; maxValue = Double.MIN_VALUE; Double[][] data; for (PlotState state : plotStateList) { data = state.getDataSet().data(); for (Double[] dArray : data) { for (Double d : dArray) { if (d > maxValue) { maxValue = d; } if (d < minValue) { minValue = d; } } } } } private void setMatrixHeightMinimum(Integer minHeight) { while (minHeight > matrix.rows() - 1) { matrix.addLine(new ArrayList>()); } } private void setMinimumListSize(Integer minWidth, List> lineToSet) { while (minWidth > lineToSet.size() - 1) { lineToSet.add(null); } } private void putPlotInFirstFreeVerticalSpaceOrAddPlot(DrawHandler drawer, Integer xFix, PlotState plotState, String info) { boolean plotFilledInFreeSpace = false; for (int ySeq = 0; ySeq < matrix.rows(); ySeq++) { List> xCoordinateList = matrix.row(ySeq); if (xFix >= xCoordinateList.size()) { setMinimumListSize(xFix, xCoordinateList); } if (xCoordinateList.get(xFix) == null) { xCoordinateList.set(xFix, createPlots(drawer, plotState, xFix, ySeq, info)); plotFilledInFreeSpace = true; break; } } // If there is no free space available for the plot, a new line must be added if (!plotFilledInFreeSpace) { ArrayList> newColumn = new ArrayList>(); setMinimumListSize(xFix, newColumn); newColumn.set(xFix, createPlots(drawer, plotState, xFix, matrix.rows(), "only x is specified -> expanded y-list")); matrix.addLine(newColumn); } } private void putPlotInFirstFreeHorizontalSpaceOrAddPlot(DrawHandler drawer, List> xCoordinateList, Integer yFix, PlotState plotState, String info) { for (int xSeq = 0; true; xSeq++) { if (xSeq == xCoordinateList.size()) { xCoordinateList.add(createPlots(drawer, plotState, xSeq, yFix, info + "added new x-entry")); return; } if (xCoordinateList.get(xSeq) == null) { xCoordinateList.set(xSeq, createPlots(drawer, plotState, xSeq, yFix, info + "replaced x-entry")); return; } } } private void putPlotInFirstFreeMatrixSpace(DrawHandler drawer, PlotState plotState) { // Go through all lines and all values in each line for (int ySeq = 0; ySeq < matrix.rows(); ySeq++) { List> oneLine = matrix.row(ySeq); for (int xSeq = 0; xSeq < oneLine.size(); xSeq++) { List oneValue = oneLine.get(xSeq); // If a free space is found use it if (oneValue == null) { oneLine.set(xSeq, createPlots(drawer, plotState, xSeq, ySeq, "no coordinate specified -> free space found")); return; } } // If the actual x-coordinates line is < than the default grid width add a new value if (oneLine.size() < gridWidth) { oneLine.add(createPlots(drawer, plotState, oneLine.size(), ySeq, "no coordinate specified -> expanded x-list")); return; } } // If every space in the matrix is occupied and the position is still not found add a new line and fill its first place List> newLine = new ArrayList>(); newLine.add(createPlots(drawer, plotState, 0, matrix.rows(), "no coordinate specified -> every matrix space occupied, expanded y-list")); matrix.addLine(newLine); } private List createPlots(DrawHandler drawer, PlotState plotState, Integer xPos, Integer yPos, String info) { List plotList = new ArrayList(); // create and add base plot plotList.add(createPlot(drawer, plotState, xPos, yPos, info)); // create and add sub plots for (PlotState subPlotState : plotState.getSubplots()) { plotList.add(createPlot(drawer, subPlotState, xPos, yPos, info)); } return plotList; } private AbstractPlot createPlot(DrawHandler drawer, PlotState plotState, int xPos, int yPos, String info) { String type = plotState.getValueValidated(PlotType.getKey(), PlotType.Bar.getValue(), PlotConstants.toStringList(PlotType.values())); log.debug("PlotGrid insert : " + type + " (" + xPos + ";" + yPos + ") " + info); PlotGridDrawConfig plotDrawConfig = new PlotGridDrawConfig(getRealSize(), new Dimension(getRectangle().width, getRectangle().height), minValue, maxValue); if (PlotType.Pie.getValue().equals(type)) { return new PiePlot(drawer, plotDrawConfig, plotState, xPos, yPos); } else if (PlotType.Line.getValue().equals(type)) { return new LinePlot(drawer, plotDrawConfig, plotState, xPos, yPos); } else if (PlotType.Scatter.getValue().equals(type)) { return new ScatterPlot(drawer, plotDrawConfig, plotState, xPos, yPos); } else { return new BarPlot(drawer, plotDrawConfig, plotState, xPos, yPos); } } public void drawPlots() { for (int row = 0; row < matrix.rows(); row++) { for (int col = 0; col < matrix.row(row).size(); col++) { List oneCell = matrix.cell(row, col); for (AbstractPlot onePlot : oneCell) { if (onePlot != null) { if (col != onePlot.getXPosition()) { log.error("Plot contains wrong coordinates: " + col + " != " + onePlot.getXPosition()); } if (row != onePlot.getYPosition()) { log.error("Plot contains wrong coordinates: " + row + " != " + onePlot.getYPosition()); } onePlot.plot(matrix.cols(), matrix.rows()); } } } } } @Override public String toString() { StringBuilder sb = new StringBuilder("------------------------------\n"); for (int i = 0; i < matrix.rows(); i++) { List> row = matrix.row(i); for (List oneCell : row) { for (AbstractPlot onePlot : oneCell) { if (onePlot == null) { sb.append("null\t"); } else { sb.append(onePlot.getPlotLineNr()).append("\t"); } } } sb.append("\n"); } return sb.append("------------------------------").toString(); } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); try { matrix = new Matrix>(); ParserResult parserState = new Parser().parse(getPanelAttributes()); parserState.setDrawer(drawer); log.debug(parserState.toString()); gridWidth = Integer.parseInt(parserState.getPlotGridValue(PlotConstants.KEY_INT_GRID_WIDTH, PlotConstants.GRID_WIDTH_DEFAULT)); fillWithPlots(parserState); drawPlots(); } catch (ParserException e) { drawer.setForegroundColor(ColorOwn.RED); drawer.setBackgroundColor(ColorOwn.WHITE); drawer.drawRectangle(0, 0, getRectangle().width - 1, getRectangle().height - 1); float x = getRectangle().getWidth() / 2.0f; drawer.print(e.getMessage(), x, getRealSize().height / 2.0, AlignHorizontal.CENTER); } } @Override protected Settings createSettings() { return new SettingsManualresizeCenter() { @Override protected List createFacets() { return listOf(PSEUDO_PLOT_FACET); // no real facets should be used } }; } @Override public ElementId getId() { return ElementId.PlotGrid; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/0000755000175000017500000000000012533641120025654 5ustar benben././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SpecialState.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SpecialState.jav0000644000175000017500000000155712533641120030747 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.specific.SpecialStateTypeFacet; import com.baselet.element.settings.SettingsNoText; public class SpecialState extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLSpecialState; } @Override protected void drawCommonContent(PropertiesParserState state) {} @Override protected Settings createSettings() { return new SettingsNoText() { @Override protected List createFacets() { return listOf(super.createFacets(), SpecialStateTypeFacet.INSTANCE); } }; } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/ActivityObject.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/ActivityObject.j0000644000175000017500000000173512533641120030760 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.settings.SettingsManualresizeCenter; public class ActivityObject extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLObject; } @Override protected void drawCommonContent(PropertiesParserState state) { state.getDrawer().drawRectangle(0, 0, getRealSize().getWidth(), getRealSize().getHeight()); } @Override protected Settings createSettings() { return new SettingsManualresizeCenter() { @Override protected List createFacets() { return listOf(super.createFacets(), SeparatorLineFacet.INSTANCE); } }; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Timer.java0000644000175000017500000000352012533641120027577 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.Arrays; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsAutoresize; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class Timer extends NewGridElement { private static final int CLOCK_DIM = 40; private final StickingPolygonGenerator timerStickingPolygonGenerator = new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addPoint(xClock(), 0); p.addPoint(x2Clock(), CLOCK_DIM); p.addPoint(xClock(), CLOCK_DIM); p.addPoint(x2Clock(), 0, true); return p; } }; @Override public ElementId getId() { return ElementId.UMLTimer; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); state.updateMinimumSize(CLOCK_DIM, CLOCK_DIM); drawer.drawLines(Arrays.asList(new PointDouble(xClock(), 0), new PointDouble(x2Clock(), CLOCK_DIM), new PointDouble(xClock(), CLOCK_DIM), new PointDouble(x2Clock(), 0), new PointDouble(xClock(), 0))); state.setStickingPolygonGenerator(timerStickingPolygonGenerator); } private int x2Clock() { return xClock() + CLOCK_DIM; } private int xClock() { return (getRealSize().width - CLOCK_DIM) / 2; } @Override protected Settings createSettings() { return new SettingsAutoresize(); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Deployment.java0000644000175000017500000000451112533641120030640 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.diagram.draw.helper.Style; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.settings.SettingsManualResizeTop; public class Deployment extends NewGridElement { @Override protected Settings createSettings() { return new SettingsManualResizeTop() { @Override protected List createFacets() { return listOf(super.createFacets(), SeparatorLineFacet.INSTANCE); } }; } @Override public ElementId getId() { return ElementId.UMLDeployment; } private static final int BORDER = 10; @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); double w = getRealSize().getWidth(); double h = getRealSize().getHeight(); List p = Arrays.asList( new PointDouble(0, BORDER), new PointDouble(BORDER, 0), new PointDouble(w, 0), new PointDouble(w, h - BORDER), new PointDouble(w - BORDER, h) ); PointDouble pLine = new PointDouble(w - BORDER, BORDER); // Fill 3d-rectangle Style oldStyle = drawer.getStyleClone(); drawer.setForegroundColor(ColorOwn.TRANSPARENT); if (oldStyle.getBackgroundColor() == ColorOwn.DEFAULT_BACKGROUND) { drawer.setBackgroundColor(ColorOwn.WHITE.transparency(Transparency.BACKGROUND).darken(80)); } else { drawer.setBackgroundColor(oldStyle.getBackgroundColor().darken(80)); } drawer.drawLines(p.get(0), p.get(1), p.get(2), p.get(3), p.get(4), pLine, p.get(0)); drawer.setStyle(oldStyle); // Draw 3d-rectangle border drawer.drawLines(p); drawer.drawLines(pLine, p.get(2)); // Draw Content-Rectangle drawer.drawRectangle(0, BORDER, w - BORDER, h - BORDER); state.getBuffer().setTopMin(BORDER); state.getBuffer().addToRight(BORDER); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Note.java0000644000175000017500000000207612533641120027431 0ustar benbenpackage com.baselet.element.elementnew.uml; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsText; public class Note extends NewGridElement { @Override protected Settings createSettings() { return new SettingsText(); } @Override public ElementId getId() { return ElementId.UMLNote; } private static final int CORNER = 12; @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); int w = getRealSize().width; int h = getRealSize().height; drawer.drawLines(p(0, 0), p(w - CORNER, 0), p(w, CORNER), p(w, h), p(0, h), p(0, 0)); drawer.drawLines(p(w - CORNER, 0), p(w - CORNER, CORNER), p(w, CORNER)); } private PointDouble p(double x, double y) { return new PointDouble(x, y); } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SyncBarHorizontal.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SyncBarHorizonta0000644000175000017500000000363612533641120031046 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.Set; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsNoText; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class SyncBarHorizontal extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLSyncBarHorizontal; } @Override protected void drawCommonContent(final PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); if (drawer.getLineWidth() == FacetConstants.LINE_WIDTH_DEFAULT) { drawer.setLineWidth(5); } Dimension s = getRealSize(); drawer.drawLine(0, s.getHeight() * 0.5, s.getWidth(), s.getHeight() * 0.5); state.setStickingPolygonGenerator(new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); double lt = state.getDrawer().getLineWidth(); double halfHeight = getRealSize().getHeight() * 0.5; p.addRectangle(new Rectangle(0.0, halfHeight - lt * 0.5, (double) getRealSize().getWidth(), lt)); return p; } }); } @Override protected Settings createSettings() { return new SettingsNoText(); } @Override public Set getResizeArea(int x, int y) { Set returnSet = super.getResizeArea(x, y); returnSet.remove(Direction.UP); returnSet.remove(Direction.DOWN); return returnSet; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/UseCase.java0000644000175000017500000000411212533641120030045 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.basics.XValues; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.settings.SettingsManualresizeCenter; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class UseCase extends NewGridElement { private final StickingPolygonGenerator stickingPolygonGenerator = new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addPoint(rect.width / 4.0, 0); p.addPoint(rect.width * 3.0 / 4, 0); p.addPoint(rect.width, rect.height / 4.0); p.addPoint(rect.width, rect.height * 3.0 / 4); p.addPoint(rect.width * 3.0 / 4, rect.height); p.addPoint(rect.width / 4.0, rect.height); p.addPoint(0, rect.height * 3.0 / 4); p.addPoint(0, (int) (rect.height / 4.0), true); return p; } }; @Override public ElementId getId() { return ElementId.UMLUseCase; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); drawer.drawEllipse(0, 0, getRealSize().width, getRealSize().height); state.setStickingPolygonGenerator(stickingPolygonGenerator); } @Override protected Settings createSettings() { return new SettingsManualresizeCenter() { @Override public XValues getXValues(double y, int height, int width) { return XValues.createForEllipse(y, height, width); } @Override protected List createFacets() { return listOf(super.createFacets(), SeparatorLineFacet.INSTANCE); } }; } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SyncBarVertical.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/SyncBarVertical.0000644000175000017500000000363212533641120030714 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.Set; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsNoText; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class SyncBarVertical extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLSyncBarVertical; } @Override protected void drawCommonContent(final PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); if (drawer.getLineWidth() == FacetConstants.LINE_WIDTH_DEFAULT) { drawer.setLineWidth(5); } Dimension s = getRealSize(); drawer.drawLine(s.getWidth() * 0.5, 0, s.getWidth() * 0.5, s.getHeight()); state.setStickingPolygonGenerator(new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); double lt = state.getDrawer().getLineWidth(); double halfWidth = getRealSize().getWidth() * 0.5; p.addRectangle(new Rectangle(halfWidth - lt * 0.5, 0.0, lt, (double) getRealSize().getHeight())); return p; } }); } @Override protected Settings createSettings() { return new SettingsNoText(); } @Override public Set getResizeArea(int x, int y) { Set returnSet = super.getResizeArea(x, y); returnSet.remove(Direction.LEFT); returnSet.remove(Direction.RIGHT); return returnSet; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Actor.java0000644000175000017500000000375312533641120027577 0ustar benbenpackage com.baselet.element.elementnew.uml; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.draw.DrawHelper; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsAutoresize; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class Actor extends NewGridElement { private final static double ACTOR_DIMENSION = 14; private final StickingPolygonGenerator actorStickingPolygonGenerator = new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { double dimension = ACTOR_DIMENSION; double hCenter = getRealSize().width / 2.0; int left = SharedUtils.realignToGrid(false, hCenter - DrawHelper.armLength(dimension), false); int right = SharedUtils.realignToGrid(false, hCenter + DrawHelper.armLength(dimension), true); int head = (int) DrawHelper.headToLegLength(dimension); StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addPoint(left, 0); p.addPoint(right, 0); p.addPoint(right, head); p.addPoint(left, head, true); return p; } }; @Override protected Settings createSettings() { return new SettingsAutoresize(); } @Override public ElementId getId() { return ElementId.UMLActor; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); double dimension = ACTOR_DIMENSION; state.updateMinimumSize(DrawHelper.armLength(dimension) * 2, DrawHelper.headToLegLength(dimension)); DrawHelper.drawActor(drawer, getRealSize().width / 2, 0, dimension); state.setStickingPolygonGenerator(actorStickingPolygonGenerator); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Frame.java0000644000175000017500000000567112533641120027562 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.Style; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.facet.common.TextBeforeFirstSeparatorCollectorFacet; import com.baselet.element.facet.common.TextBeforeFirstSeparatorCollectorFacet.TextBeforeFirstSeparatorCollectorFacetResponse; import com.baselet.element.settings.SettingsManualResizeTop; public class Frame extends NewGridElement { @Override protected Settings createSettings() { return new SettingsManualResizeTop() { @Override protected List createFacets() { return listOf(super.createFacets(), TextBeforeFirstSeparatorCollectorFacet.INSTANCE, SeparatorLineFacet.INSTANCE); } }; } @Override public ElementId getId() { return ElementId.UMLFrame; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); drawer.drawRectangle(0, 0, getRealSize().getWidth(), getRealSize().getHeight()); TextBeforeFirstSeparatorCollectorFacetResponse packageTitleResponse = state.getFacetResponse(TextBeforeFirstSeparatorCollectorFacet.class, null); if (packageTitleResponse != null) { double top = state.getBuffer().getTop(); double textDistanceToTop = drawer.getDistanceBorderToText() + top; double heightOfTitle = drawer.getDistanceBorderToText() + textDistanceToTop; double width = 0; for (String line : packageTitleResponse.getLines()) { width = Math.max(width, drawer.textWidth(line)); heightOfTitle += drawer.textHeightMax(); } double corner = heightOfTitle * 0.4; double rightSpace = corner * 1.5; double lowerLeftSpace = state.getXLimits(heightOfTitle).getLeft(); width += rightSpace + lowerLeftSpace; Style style = drawer.getStyleClone(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); drawer.drawLines(new PointDouble(width, top), new PointDouble(width, heightOfTitle - corner), new PointDouble(width - corner, heightOfTitle), new PointDouble(lowerLeftSpace, heightOfTitle)); drawer.setStyle(style); // reset style to state before manipulations for drawing the template class state.getBuffer().setTopMin(heightOfTitle); double printHeightIter = textDistanceToTop; for (String line : packageTitleResponse.getLines()) { printHeightIter += drawer.textHeightMax(); drawer.print(line, lowerLeftSpace + drawer.getDistanceBorderToText(), printHeightIter, AlignHorizontal.LEFT); } } } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Package.java0000644000175000017500000000564112533641120030060 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.DrawHandler.Layer; import com.baselet.element.NewGridElement; import com.baselet.element.draw.DrawHelper; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; import com.baselet.element.facet.common.TextBeforeFirstSeparatorCollectorFacet; import com.baselet.element.facet.common.TextBeforeFirstSeparatorCollectorFacet.TextBeforeFirstSeparatorCollectorFacetResponse; import com.baselet.element.settings.SettingsManualresizeCenter; import com.baselet.element.sticking.polygon.PointDoubleStickingPolygonGenerator; public class Package extends NewGridElement { @Override protected Settings createSettings() { return new SettingsManualresizeCenter() { @Override protected List createFacets() { return listOf(super.createFacets(), TextBeforeFirstSeparatorCollectorFacet.INSTANCE, SeparatorLineFacet.INSTANCE); } }; } @Override public ElementId getId() { return ElementId.UMLPackage; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); List packageTitle = getTitleLines(state); double packageHeight = 0; double packageWidth = getRealSize().getWidth() / 2.5; double txtHeight = drawer.textHeightMaxWithSpace(); for (String line : packageTitle) { packageHeight += txtHeight; packageWidth = Math.max(packageWidth, drawer.textWidth(line) + drawer.getDistanceBorderToText() * 2); drawer.setLayer(Layer.Foreground); // text should be in front of the package-border drawer.print(line, new PointDouble(drawer.getDistanceBorderToText(), packageHeight), AlignHorizontal.LEFT); drawer.setLayer(Layer.Background); } packageHeight += drawer.getDistanceBorderToText(); int height = getRealSize().getHeight(); int width = getRealSize().getWidth(); List points = DrawHelper.drawPackage(drawer, 0, 0, packageHeight, packageWidth, height, width); state.getBuffer().setTopMin(packageHeight); state.setStickingPolygonGenerator(new PointDoubleStickingPolygonGenerator(points)); } private static List getTitleLines(PropertiesParserState state) { List packageTitle; TextBeforeFirstSeparatorCollectorFacetResponse packageTitleResponse = state.getFacetResponse(TextBeforeFirstSeparatorCollectorFacet.class, null); if (packageTitleResponse != null) { packageTitle = packageTitleResponse.getLines(); } else { packageTitle = Arrays.asList(""); } return packageTitle; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Hierarchy.java0000644000175000017500000000234612533641120030442 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.ElementId; import com.baselet.control.enums.ElementStyle; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; public class Hierarchy extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLHierarchy; } @Override protected void drawCommonContent(PropertiesParserState state) { state.getDrawer().drawRectangle(0, 0, getRealSize().getWidth(), getRealSize().getHeight()); } @Override protected Settings createSettings() { return new Settings() { @Override public ElementStyle getElementStyle() { return ElementStyle.SIMPLE; } @Override public AlignHorizontal getHAlign() { return AlignHorizontal.LEFT; // not really used because there is no default text, but important if autoresize is used because autoresize adds to left and right if halign is center } @Override protected List createFacets() { return Settings.HIERARCHY; } }; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Class.java0000644000175000017500000000235112533641120027565 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineWithHalignChangeFacet; import com.baselet.element.facet.specific.ActiveClassFacet; import com.baselet.element.facet.specific.InnerClassFacet; import com.baselet.element.facet.specific.TemplateClassFacet; import com.baselet.element.settings.SettingsManualResizeTop; public class Class extends NewGridElement { @Override protected Settings createSettings() { return new SettingsManualResizeTop() { @Override protected List createFacets() { return listOf(super.createFacets(), InnerClassFacet.INSTANCE, SeparatorLineWithHalignChangeFacet.INSTANCE, ActiveClassFacet.INSTANCE, TemplateClassFacet.INSTANCE); } }; } @Override public ElementId getId() { return ElementId.UMLClass; } @Override protected void drawCommonContent(PropertiesParserState state) { // nothing to do here; even the basic border is drawn by TemplateClassFacet } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/State.java0000644000175000017500000000210312533641120027573 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineWithHalignChangeFacet; import com.baselet.element.facet.specific.StateTypeFacet; import com.baselet.element.facet.specific.SubStateSymbolFacet; import com.baselet.element.settings.SettingsManualresizeCenter; public class State extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLState; } @Override protected void drawCommonContent(PropertiesParserState state) {} @Override protected Settings createSettings() { return new SettingsManualresizeCenter() { @Override protected List createFacets() { return listOf(super.createFacets(), SeparatorLineWithHalignChangeFacet.INSTANCE, StateTypeFacet.INSTANCE, SubStateSymbolFacet.INSTANCE); } }; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Generic.java0000644000175000017500000000212512533641120030073 0ustar benbenpackage com.baselet.element.elementnew.uml; import java.util.List; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineWithHalignChangeFacet; import com.baselet.element.facet.specific.UpperRightSymbolFacet; import com.baselet.element.settings.SettingsManualResizeTop; public class Generic extends NewGridElement { @Override public ElementId getId() { return ElementId.UMLGeneric; } @Override protected void drawCommonContent(PropertiesParserState state) { state.getDrawer().drawRectangle(0, 0, getRealSize().getWidth(), getRealSize().getHeight()); } @Override protected Settings createSettings() { return new SettingsManualResizeTop() { @Override protected List createFacets() { return listOf(super.createFacets(), UpperRightSymbolFacet.INSTANCE, SeparatorLineWithHalignChangeFacet.INSTANCE); } }; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/elementnew/uml/Interface.java0000644000175000017500000000336012533641120030421 0ustar benbenpackage com.baselet.element.elementnew.uml; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.NewGridElement; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.settings.SettingsAutoresize; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.StickingPolygonGenerator; public class Interface extends NewGridElement { private static final int TOP_DISTANCE = 10; private static final int CIRCLE_SIZE = 20; private final StickingPolygonGenerator interfacePolygonGenerator = new StickingPolygonGenerator() { @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addRectangle(circleRect()); return p; } }; @Override public ElementId getId() { return ElementId.UMLInterface; } @Override protected void drawCommonContent(PropertiesParserState state) { DrawHandler drawer = state.getDrawer(); state.getBuffer().setTopMin(TOP_DISTANCE + CIRCLE_SIZE);// space reserved for the top circle Rectangle circleRect = circleRect(); drawer.drawCircle(circleRect.x + CIRCLE_SIZE * 0.5, circleRect.y + CIRCLE_SIZE * 0.5, CIRCLE_SIZE * 0.5); state.setStickingPolygonGenerator(interfacePolygonGenerator); } private Rectangle circleRect() { int middlePos = (int) (getRealSize().getWidth() * 0.5 - CIRCLE_SIZE * 0.5); return new Rectangle(middlePos, TOP_DISTANCE, CIRCLE_SIZE, CIRCLE_SIZE); } @Override protected Settings createSettings() { return new SettingsAutoresize(); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/0000755000175000017500000000000012533641120024531 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/0000755000175000017500000000000012533641120025613 5ustar benben././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionUtils.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionU0000644000175000017500000000741612533641120030766 0ustar benbenpackage com.baselet.element.relation.facet; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.Direction; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.relation.helper.LineDescriptionEnum; import com.baselet.element.relation.helper.RelationPointHandler; public class LineDescriptionUtils { static PointDouble calcPosOfEndText(DrawHandler drawer, String text, RelationPointHandler relationPoints, LineDescriptionEnum enumVal) { Boolean printOnStart = enumVal.isStart(); Line line = printOnStart ? relationPoints.getFirstLine() : relationPoints.getLastLine(); PointDouble pointText = line.getPointOnLineWithDistanceFrom(printOnStart, 15); // distance from lineend (because of arrows,...) Direction lineDirection = line.getDirectionOfLine(printOnStart); // Default Positioning if (lineDirection == Direction.RIGHT) { pointText = new PointDouble(pointText.getX() - drawer.textWidth(text) - drawer.getDistanceBorderToText(), pointText.getY() + drawer.textHeightMax() + LineDescriptionFacet.LOWER_Y_DIST_TO_LINE); } else if (lineDirection == Direction.LEFT) { pointText = new PointDouble(pointText.getX() + LineDescriptionFacet.X_DIST_TO_LINE, pointText.getY() + drawer.textHeightMax() + LineDescriptionFacet.LOWER_Y_DIST_TO_LINE); } else if (lineDirection == Direction.UP) { pointText = new PointDouble(pointText.getX() + LineDescriptionFacet.X_DIST_TO_LINE, pointText.getY() + drawer.textHeightMax() + LineDescriptionFacet.LOWER_Y_DIST_TO_LINE); } else if (lineDirection == Direction.DOWN) { pointText = new PointDouble(pointText.getX() + LineDescriptionFacet.X_DIST_TO_LINE, pointText.getY() - LineDescriptionFacet.LOWER_Y_DIST_TO_LINE); } // r1 and r2 are place on top of the line if it is horizontal or on the inner side if the line is vertical if (enumVal.isRoleStartOrEnd()) { if (lineDirection == Direction.UP) { pointText = new PointDouble(pointText.getX(), pointText.getY() + drawer.textHeightMaxWithSpace()); } else if (lineDirection == Direction.DOWN) { pointText = new PointDouble(pointText.getX(), pointText.getY() - drawer.textHeightMaxWithSpace()); } else { pointText = new PointDouble(pointText.getX(), pointText.getY() - drawer.textHeightMax() - LineDescriptionFacet.UPPER_Y_DIST_TO_LINE); } } return pointText; } static String replaceArrowsWithUtf8Characters(String text) { if (text.startsWith("< ")) { text = "\u25C4" + text.substring(1); } if (text.endsWith(" >")) { text = text.substring(0, text.length() - 1) + "\u25BA"; } else if (text.endsWith(" ^")) { text = text.substring(0, text.length() - 1) + "\u25B2"; } else if (text.endsWith(" v")) { text = text.substring(0, text.length() - 1) + "\u25BC"; } return text; } static PointDouble calcPosOfMiddleText(DrawHandler drawer, String text, Line line, int currentLineNr, double halfMiddleBlockHeight) { double textWidth = drawer.textWidth(text); boolean horizontalLine = line.getDirectionOfLine(true).isHorizontal(); PointDouble center = line.getCenter(); double textX, textY; double previousLinesUsedSpace = currentLineNr * drawer.textHeightMaxWithSpace(); if (horizontalLine) { textX = center.getX() - textWidth / 2; textY = center.getY() + previousLinesUsedSpace - LineDescriptionFacet.MIDDLE_DISTANCE_TO_LINE; } else { textX = center.getX() + LineDescriptionFacet.X_DIST_TO_LINE; textY = center.getY() + previousLinesUsedSpace - halfMiddleBlockHeight + drawer.textHeightMaxWithSpace(); // must use textHeightMaxWithSpace and not the height of the line to make sure the text looks good (see Issue 235) } return new PointDouble(textX, textY); } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/SettingsRelation.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/SettingsRelation0000644000175000017500000000110512533641120031031 0ustar benbenpackage com.baselet.element.relation.facet; import java.util.List; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; import com.baselet.element.relation.helper.RelationPointHandler; public abstract class SettingsRelation extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.NORESIZE; } @Override protected List createFacets() { return Settings.RELATION; } public abstract RelationPointHandler getRelationPoints(); } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/RelationLineTypeFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/RelationLineType0000644000175000017500000003456412533641120031001 0ustar benbenpackage com.baselet.element.relation.facet; import java.util.Arrays; import java.util.List; import org.apache.log4j.Logger; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Line; import com.baselet.control.enums.LineType; import com.baselet.control.enums.RegexValueHolder; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.relation.helper.RelationPointHandler; import com.baselet.element.relation.helper.ResizableObject; import com.baselet.element.sticking.PointDoubleIndexed; /** * must be in first-run because it manipulates the relation position and size (in case of [text]-[text] line which can possibly exceed the old relation size) * must handle values in parsingFinished when drawer-setup is finished */ public class RelationLineTypeFacet extends FirstRunKeyValueFacet { static final String KEY = "lt"; private static class Match { private final String text; private final T type; public Match(String matchedText, T matchedObject) { super(); this.text = matchedText; this.type = matchedObject; } } public static final RelationLineTypeFacet INSTANCE = new RelationLineTypeFacet(); private RelationLineTypeFacet() {} private final Logger log = Logger.getLogger(RelationLineTypeFacet.class); /** * all arrowtypes and linetypes to expect (order is important because eg << must be before < to be recognized correctly, therefore there are 2 shared lists. also linetype .. must be before .) */ private static final List SHARED_ARROW_STRINGS_BEFORE = Arrays.asList(ArrowEnd.CIRCLE_CROSS, ArrowEnd.CIRCLE, ArrowEnd.DIAGONAL_CROSS); private static final List SHARED_ARROW_STRINGS_AFTER = Arrays.asList(ArrowEnd.BOX); private static final List LEFT_ARROW_STRINGS = SharedUtils.mergeLists(SHARED_ARROW_STRINGS_BEFORE, Arrays.asList(ArrowEnd.LEFT_BOX, ArrowEnd.LEFT_FILLED_DIAMOND, ArrowEnd.LEFT_DIAMOND, ArrowEnd.LEFT_FILLED_CLOSED, ArrowEnd.LEFT_CLOSED, ArrowEnd.LEFT_NORMAL, ArrowEnd.LEFT_INVERTED, ArrowEnd.LEFT_INTERFACE_OPEN), SHARED_ARROW_STRINGS_AFTER); private static final List RIGHT_ARROW_STRINGS = SharedUtils.mergeLists(SHARED_ARROW_STRINGS_BEFORE, Arrays.asList(ArrowEnd.RIGHT_BOX, ArrowEnd.RIGHT_FILLED_DIAMOND, ArrowEnd.RIGHT_DIAMOND, ArrowEnd.RIGHT_FILLED_CLOSED, ArrowEnd.RIGHT_CLOSED, ArrowEnd.RIGHT_NORMAL, ArrowEnd.RIGHT_INVERTED, ArrowEnd.RIGHT_INTERFACE_OPEN), SHARED_ARROW_STRINGS_AFTER); private static final List LINE_TYPES = Arrays.asList(LineType.SOLID, LineType.DOTTED, LineType.DASHED); public RelationPointHandler getRelationPoints(PropertiesParserState state) { return ((SettingsRelation) state.getSettings()).getRelationPoints(); } private static class Remaining { String value; public Remaining(String value) { this.value = value; } @Override public String toString() { // is used in error message return value; } } @Override public void handleValue(String value, PropertiesParserState state) {} private String listToString(List valueHolderList) { StringBuilder sb = new StringBuilder(); for (RegexValueHolder r : valueHolderList) { String simpleRegex = r.getRegexValue().replace(ArrowEnd.BOX_REGEX, "[text]").replaceAll("\\\\", ""); sb.append(simpleRegex).append(','); } sb.setLength(sb.length() - 1); return sb.toString(); } /** * if no explicit linetype is set, draw a solid line without arrows */ public static void drawDefaultLineAndArrows(DrawHandler drawer, RelationPointHandler relationPoints) { drawLineAndArrows(drawer, relationPoints, new Match("", LineType.SOLID), new Match("", null), new Match("", null)); } private static void drawLineAndArrows(DrawHandler drawer, RelationPointHandler relationPoints, Match lineType, Match leftArrow, Match rightArrow) { drawLineBetweenPoints(drawer, relationPoints, lineType.type); drawArrowEnds(drawer, relationPoints, leftArrow, rightArrow); relationPoints.resizeRectAndReposPoints(); // line description and relation-endings can change the relation size, therefore recalc it now } private static void drawArrowEnds(DrawHandler drawer, RelationPointHandler relationPoints, Match leftArrow, Match rightArrow) { ColorOwn oldBgColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(oldBgColor.transparency(Transparency.FOREGROUND)); // arrow background is not transparent print(drawer, relationPoints, leftArrow, relationPoints.getFirstLine(), true); print(drawer, relationPoints, rightArrow, relationPoints.getLastLine(), false); drawer.setBackgroundColor(oldBgColor); // reset background } private static void print(DrawHandler drawer, ResizableObject relationPoints, Match match, Line line, boolean drawOnLineStart) { relationPoints.resetPointMinSize(((PointDoubleIndexed) line.getPoint(drawOnLineStart)).getIndex()); if (match.type != null) { match.type.print(drawer, line, drawOnLineStart, match.text, relationPoints); } } private static void drawLineBetweenPoints(DrawHandler drawer, RelationPointHandler relationPoints, LineType lineType) { LineType oldLt = drawer.getLineType(); drawer.setLineType(lineType); relationPoints.drawLinesBetweenPoints(drawer); drawer.setLineType(oldLt); } private Match extractPart(List valueHolderList, Remaining remaining) { for (T valueHolder : valueHolderList) { String regex = "^" + valueHolder.getRegexValue(); // only match from start of the line (left to right) String newRemainingValue = remaining.value.replaceFirst(regex, ""); if (!remaining.value.equals(newRemainingValue)) { String removedPart = remaining.value.substring(0, remaining.value.length() - newRemainingValue.length()); remaining.value = newRemainingValue; return new Match(removedPart, valueHolder); } } return new Match("", null); } private String getValueNotNull(Match valueHolder) { if (valueHolder.type == null) { return ""; } else { return valueHolder.type.getRegexValue(); } } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { if (handledLines.isEmpty()) { drawDefaultLineAndArrows(state.getDrawer(), getRelationPoints(state)); } else if (handledLines.size() == 1) { RelationPointHandler relationPoints = getRelationPoints(state); String value = extractValue(handledLines.get(0)); Remaining remaining = new Remaining(value); Match leftArrow = extractPart(LEFT_ARROW_STRINGS, remaining); Match lineType = extractPart(LINE_TYPES, remaining); if (leftArrow.type == null && lineType.type == null) { throw new StyleException("left arrow must be one of the following or empty:\n" + listToString(LEFT_ARROW_STRINGS)); } if (lineType.type == null) { throw new StyleException("lineType must be specified. One of: " + listToString(LINE_TYPES)); } Match rightArrow = extractPart(RIGHT_ARROW_STRINGS, remaining); if (rightArrow.type == null && !remaining.value.isEmpty()) { throw new StyleException("right arrow must be one of the following or empty:\n" + listToString(RIGHT_ARROW_STRINGS)); } if (!remaining.value.isEmpty()) { throw new StyleException("Unknown part after rightArrow: " + remaining); } log.debug("Split Relation " + value + " into following parts: " + getValueNotNull(leftArrow) + " | " + getValueNotNull(lineType) + " | " + getValueNotNull(rightArrow)); drawLineAndArrows(state.getDrawer(), relationPoints, lineType, leftArrow, rightArrow); relationPoints.resizeRectAndReposPoints(); // apply the (possible) changes now to make sure the following facets use correct coordinates } else { throw new StyleException("Only one lineType allowed"); } } @Override public KeyValue getKeyValue() { return new KeyValue( KEY, new ValueInfo("<-", "left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAq0lEQVR42mL8z4AAX3gYyAdMCOabUsUf1DDpR4fqld0cFJjE8P////////+eL2Oy/z9FAGLSdgOV5b//U27SaQeR7u///1Ns0u0Inor3/ykHDLcZqAP+M/x/HuJw/T813PT////1Ks2/KTeJiYGBIeD8S8MTVPDf//////8/rpHzmQpuYmBgsLgsbLiFKm76////bZuQ55SncQiYrvCaApMYkUuVDwIUeA4wABeKjdP2NRIjAAAAAElFTkSuQmCC") , new ValueInfo("<.", "left arrow with dashed line", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAsUlEQVR42mL8z4AAX3gYyAdMCOabUsUf1DDpR4fqld0cFJjE8P////////+eL2Oy/z9FAGLSdgOV5b//U27SaQeR7u///1Ns0u0Inor3/ykHDLdhAVb///////Xkcur/M/x/HuJw/T813PT////1Ks2/KTeJiYGBIeD8S8MTDBQDiIHHNXI+U8FNDAwMFpeFDbdQxU3///+/bRPynPI0DgHTFV5TYBIjcqnyQYACzwEGAD/RpzQKsM6sAAAAAElFTkSuQmCC") , new ValueInfo("<..", "left arrow with dotted line", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAArElEQVR42mL8z4AAX3gYyAdMCOabUsUf1DDpR4fqld0cFJjE8P////////+eL2Oy/z9FAGLSdgOV5b//U27SaQeR7u///1Ns0u0Inor3/ykHDLcZGB7X1/+nHDH8fx7icP0/Ndz0////9SrNvyk3iYmBgSHg/EvDEwwUA4iBxzVyPlPBTQwMDBaXhQ23UMVN////v20T8pzyNA4B0xVeU2ASI3Kp8kGAAs8BBgAP7rtyPzvx8QAAAABJRU5ErkJggg==") , new ValueInfo("<<-", "closed left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAArElEQVR42mL8z4AAd1QYyAdMCOabUlUGapj0o0P1CgNF4P////////89X8Zk/38ohzwA0bzdQGX57/+Um3TaQaT7O8JYsk26HcFT8R7ZgeSadJuB4TGcQ0l4M/x/HuJw/T813PT////1Ks2/KTeJiYGBIeD8S8MTDBQDiIHHNXI+U8FNDAwMFpeFDbdQ5iRGeITdSZRY858qOVjlsDPDG6q4iYGB4YMABSYBBgB/rAWtC0QJWQAAAABJRU5ErkJggg==") , new ValueInfo("<<<-", "filled closed left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAmklEQVR42mL8z4AAd1QYyAdMCOabCFUGSsB/KPhewsYI55ADoJp/z+JjQjKWfJO2y7KgOJBck04bs6J5lTyTbgeyMDFQw6TbDNQB/xn+P/cUZaaKm/7//79eVpJKJv3/nCUpRrFJjJDcciKB9cYfBob/lOcWiyvB0taUBTkj3Bl3Ev8d+0+NfPf////pDK8pDycI+CBAgZMAAwDOwWE1BFRLXwAAAABJRU5ErkJggg==") , new ValueInfo("<<<<-", "diamond left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAA3UlEQVR42mL8z4AAPzgYyAdMCOabUs7EO1Qw6UeH6pXVDLoUmPX/////////ni9jsv////+3EzgSbv8nC0BM2m6gsvw3RIBssxj+//9/2kGk+ztCiEyzGP7fjuCpeI8qSJZZDLcZGB5jCl8nPbwZ/j8PcbiObtBhg5jH5ITTepXm38hi92MsDpMZd59zdI7DRb43K8z+TXYq+H9cI+czhLVao+Q9Benp///f9Sqb////f93F5fr//xSZ9P//bZuQ6zkam///p9ik//+nMxR8J9ug/4zIpcobEQpKFcAAdWYW1hzT7fsAAAAASUVORK5CYII=") , new ValueInfo("<<<<<-", "filled diamond left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAQCAAAAAB/mQ0/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAyUlEQVR42mL8z4AAPzgYyAdMCOabCE6NSxQY9R8KvpewMTIwMJrc+E8mgJr0exYf1HVM3rcpMWm7LAuShwNvk2vSaWNWFA+zskTdJsek24EsTOiBx8GaQLJZDLcZqAP+M/x/7inKjC7MLx39mJxwWi8riWIOs7bJYTLj7nOWpBjCIHWp2b/JT0/H1XWg6UBCruQ9JSnz/+96eWsGBgZBVafrZKZxRngOvpP47wX7734fivPd////pzMUfP9PNmBELlXeiFCQoAADAGzWnc70WHTSAAAAAElFTkSuQmCC") , new ValueInfo("()-", "circle left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAXCAAAAACJq4aEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAA/0lEQVR42mL8z0AtwARjXKi15WRkNS09QalRNzwD2Zvf//88WTzV9Qq5Zv3//////90S/b//Q8Fkic3/yQIM/////79b5TiS0GWFzWQbdV3iOIrYZYnL5Brl0Y8mONmFTKPOK/xGF9U5ToZRTAwMa5NZ0OMifi15ieGADYaozQEyjGL8z8D5ngNd9Afvb7KMYsSSdxjJSKAsDAwcPzBdxfKbrLAywcx2FwzIC3aHIxiiRxzIy4NUTFcGGlPQjJ8iYUFmyUDFPIheMqiQXzL8/79bhFrl1f//1z0Umvd////9eLeOy2XyTPoPT+oX1h4484PFwCHYgtzymJF6NQ5gAGG56ureP9K3AAAAAElFTkSuQmCC") , new ValueInfo("(+)-", "circle left arrow with plus symbol", "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAXCAAAAACJq4aEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABD0lEQVR42mL8z0AtwARjXKi15WRkNS09QalRNzwD2Zvf//88WTzV9Qq5Zv3//////90S/b//Q8Fkic3/yQIM/////79b5TiS0GWFzWQbdV3iOIrYZYnL5Brl0Y/sxP///092IdOo8wq/0Yz6r3OcDKOYGBjWJrOgx0X8WvISwwEbDFGbA2QYxfifgfM9B4IDAT94f5NlFON/BgYGRqSUhsolOoGyMDBw/OCA6EdyFctvssLKBDPbXTAgL9gdjmCIHnEgLw9SMV0ZaExBM36KhAWZJQMV8yB6yaBCfsnw//9uEWqVV///X/dQaN7//f/34906LpfJM+k/PFVeWHvgzA8WA4dgC3LLY0bq1TiAAQAcj+vskkcbaQAAAABJRU5ErkJggg==") , new ValueInfo("x-", "diagonally crossed left arrow", "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAXCAAAAACJq4aEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAf0lEQVR42uzUwQ3AIAgFUHQCjq7gnB3J3uhOsgG9WErTS4vcWk6GxBejX5JAVGX4CsWmyVMU11V7W/VZMoqw3VbvSikVvJKhhuGWLCWEbUK6UEK4+CWBqI8jkiHoVCYMoXcV94JxuYpLey/nfirdQ6UjDIxmMqAnDukfyI9rHwBCzBVSiqTGJwAAAABJRU5ErkJggg==") , new ValueInfo("[txt]-", "box end with text", "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAXCAAAAACJq4aEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAzUlEQVR42mL8z0AtwMLAiF3iPxlGYdfESLqrmKjmv1GjyDDqOQM6g2TA+J/xPwMDAwPPF6gAlMFIVrpiYGBguPB1jwibFsONX/++7nFiosiDhxhWfrN5+drx+yGGlf8gziIVwD3I+J+h/uoXtyKYz8jwIJJR//T4jzJQYBRSuNx6++AGRanhP8P//////2f4/Vd3xSrd3/8ZfkP4/0kGMKNsOFNC//8PLP1vw3mdTKNgYcXwB5osoAwKgh1TfJhkZxYcZS8jOUZRrcoBDABbMrpBXVzS8wAAAABJRU5ErkJggg==") , new ValueInfo("[txt]<-", "box end with text and arrow pointing to it", "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAXCAAAAACJq4aEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABPklEQVR42qyVv0sDMRTHX6SDpQ4KDg4OCicUpKDgJDc4OStU8A+40UkouHVwEZw6dXRUXBwcHG5wEgsOh2Cp2KVT/VVRsGAhHB8HSe/AGy7HvS0v5JNvXr55UUheURCVPEEGVPIiZa9qIrfzpUEN80INaoujXFCjo6UHfzKlLISkEAB9Mr92TdowqL5J9CPU1YpzqrFGlUyiZPJ3G7PHP2CNCsQP2tC5D8QPAWR36uATMqAa4t3MvLzNtRriaaBrbysUChERhdTbw819+RuKqg6aZVuYmDKHy+vm6kC4cA611QFjvnr66D3G9tgKXldbmVTpsHJ2XtGIjnx1W977tjeDW/R2YLuGW+yMUei6c2mNYlyXmCqg61afbVFJDweA5sJ7OpQxw7/WF2W/ptNVPQXKoiGrnBpyQXL7cn4HACsYkiEdOFqWAAAAAElFTkSuQmCC")); } } ././@LongLink0000644000000000000000000000016600000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionPositionFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionP0000644000175000017500000000431712533641120030756 0ustar benbenpackage com.baselet.element.relation.facet; import java.util.HashMap; import java.util.Map; import com.baselet.control.basics.geom.Point; import com.baselet.diagram.draw.helper.StyleException; import com.baselet.element.facet.FirstRunKeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.relation.helper.LineDescriptionEnum; public class LineDescriptionPositionFacet extends FirstRunKeyValueFacet { private static final int MAX_DISP = 200; public static final String POS = "pos"; public static final LineDescriptionPositionFacet INSTANCE_MESSAGE_START = new LineDescriptionPositionFacet(LineDescriptionEnum.MESSAGE_START); public static final LineDescriptionPositionFacet INSTANCE_MESSAGE_END = new LineDescriptionPositionFacet(LineDescriptionEnum.MESSAGE_END); public static final LineDescriptionPositionFacet INSTANCE_ROLE_START = new LineDescriptionPositionFacet(LineDescriptionEnum.ROLE_START); public static final LineDescriptionPositionFacet INSTANCE_ROLE_END = new LineDescriptionPositionFacet(LineDescriptionEnum.ROLE_END); private final LineDescriptionEnum lineDesc; public LineDescriptionPositionFacet(LineDescriptionEnum lineDesc) { super(); this.lineDesc = lineDesc; } @Override public KeyValue getKeyValue() { return new KeyValue(lineDesc.getKey() + POS, false, "-5,7", "comma separated integers as displacement of " + lineDesc + " text (first=horizontal, second=vertical)"); } @Override public void handleValue(String value, PropertiesParserState state) { try { Map displacements = state.getOrInitFacetResponse(LineDescriptionPositionFacet.class, new HashMap()); String[] split = value.split(","); int x = Integer.parseInt(split[0]); int y = Integer.parseInt(split[1]); if (Math.abs(x) > MAX_DISP || Math.abs(y) > MAX_DISP) { throw new StyleException("max allowed positive or negative displacement value is " + MAX_DISP); } displacements.put(lineDesc.getKey(), new Point(x, y)); } catch (Exception e) { if (e instanceof StyleException) { throw (StyleException) e; } throw new StyleException("value must be ,"); } } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/ArrowEnd.java0000644000175000017500000001776412533641120030216 0ustar benbenpackage com.baselet.element.relation.facet; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.Direction; import com.baselet.control.enums.RegexValueHolder; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.relation.helper.RelationDrawer; import com.baselet.element.relation.helper.RelationDrawer.ArrowEndType; import com.baselet.element.relation.helper.ResizableObject; abstract class ArrowEnd implements RegexValueHolder { static final String BOX_REGEX = "\\[[^\\]]*\\]"; private final String regexValue; public ArrowEnd(String regexValue) { super(); this.regexValue = regexValue; } @Override public String getRegexValue() { return regexValue; } abstract void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject); static ArrowEnd BOX = new ArrowEnd(BOX_REGEX) { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { String textWithoutBox = matchedText.substring(1, matchedText.length() - 1); RelationDrawer.drawBoxArrow(drawer, lineToDraw, drawOnLineStart, textWithoutBox, resizableObject); } }; static ArrowEnd LEFT_BOX = new ArrowEnd(BOX_REGEX + "<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { String textWithoutBox = matchedText.substring(1, matchedText.length() - 2); Rectangle r = RelationDrawer.drawBoxArrow(drawer, lineToDraw, drawOnLineStart, textWithoutBox, resizableObject); PointDouble intersection = lineToDraw.getIntersectionPoints(r).get(0); RelationDrawer.drawArrowToLine(intersection, drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, false); } }; static ArrowEnd LEFT_NORMAL = new ArrowEnd("<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, false); } }; static ArrowEnd LEFT_INVERTED = new ArrowEnd(">") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, true); } }; static ArrowEnd LEFT_CLOSED = new ArrowEnd("<<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.CLOSED, false, false); } }; static ArrowEnd LEFT_FILLED_CLOSED = new ArrowEnd("<<<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.CLOSED, true, false); } }; static ArrowEnd LEFT_DIAMOND = new ArrowEnd("<<<<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.DIAMOND, false, false); } }; static ArrowEnd LEFT_FILLED_DIAMOND = new ArrowEnd("<<<<<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.DIAMOND, true, false); } }; static ArrowEnd LEFT_INTERFACE_OPEN = new ArrowEnd("\\)") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawCircle(drawer, lineToDraw, drawOnLineStart, resizableObject, Direction.LEFT, false); } }; static ArrowEnd RIGHT_BOX = new ArrowEnd(">" + BOX_REGEX) { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { String textWithoutBox = matchedText.substring(2, matchedText.length() - 1); Rectangle r = RelationDrawer.drawBoxArrow(drawer, lineToDraw, drawOnLineStart, textWithoutBox, resizableObject); PointDouble intersection = lineToDraw.getIntersectionPoints(r).get(0); RelationDrawer.drawArrowToLine(intersection, drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, false); } }; static ArrowEnd RIGHT_NORMAL = new ArrowEnd(">") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, false); } }; static ArrowEnd RIGHT_INVERTED = new ArrowEnd("<") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.NORMAL, false, true); } }; static ArrowEnd RIGHT_CLOSED = new ArrowEnd(">>") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.CLOSED, false, false); } }; static ArrowEnd RIGHT_FILLED_CLOSED = new ArrowEnd(">>>") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.CLOSED, true, false); } }; static ArrowEnd RIGHT_DIAMOND = new ArrowEnd(">>>>") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.DIAMOND, false, false); } }; static ArrowEnd RIGHT_FILLED_DIAMOND = new ArrowEnd(">>>>>") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawArrowToLine(drawer, lineToDraw, drawOnLineStart, ArrowEndType.DIAMOND, true, false); } }; static ArrowEnd RIGHT_INTERFACE_OPEN = new ArrowEnd("\\(") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawCircle(drawer, lineToDraw, drawOnLineStart, resizableObject, Direction.RIGHT, false); } }; static ArrowEnd CIRCLE_CROSS = new ArrowEnd("\\(\\+\\)") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawCircle(drawer, lineToDraw, drawOnLineStart, resizableObject, null, true); } }; static ArrowEnd CIRCLE = new ArrowEnd("\\(\\)") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawCircle(drawer, lineToDraw, drawOnLineStart, resizableObject, null, false); } }; static ArrowEnd DIAGONAL_CROSS = new ArrowEnd("x") { @Override public void print(DrawHandler drawer, Line lineToDraw, boolean drawOnLineStart, String matchedText, ResizableObject resizableObject) { RelationDrawer.drawDiagonalCross(drawer, lineToDraw, drawOnLineStart, resizableObject, null, false); } }; }././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionFacet.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/facet/LineDescriptionF0000644000175000017500000001372612533641120030750 0ustar benbenpackage com.baselet.element.relation.facet; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Priority; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.facet.FirstRunFacet; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.relation.helper.LineDescriptionEnum; import com.baselet.element.relation.helper.RelationPointHandler; import com.baselet.gui.AutocompletionText; /** * must be in first-run after LineDescriptionPositionFacet (because the displacement must be applied) * and before RelationLineTypeFacet and before drawCommonComponents (because the text changes the relationpoint placements and the size of the relation */ public class LineDescriptionFacet extends FirstRunFacet { static final int X_DIST_TO_LINE = 4; static final int LOWER_Y_DIST_TO_LINE = 1; static final int UPPER_Y_DIST_TO_LINE = 5; static final int MIDDLE_DISTANCE_TO_LINE = 4; public static final LineDescriptionFacet INSTANCE = new LineDescriptionFacet(); private LineDescriptionFacet() {} @Override public boolean checkStart(String line, PropertiesParserState state) { return !line.startsWith(RelationLineTypeFacet.KEY + KeyValueFacet.SEP); // because middle text has no prefix, apply alway except for the lt= line } @Override public List getAutocompletionStrings() { return Arrays.asList( new AutocompletionText(LineDescriptionEnum.MESSAGE_START.getKey() + KeyValueFacet.SEP, "message at start"), new AutocompletionText(LineDescriptionEnum.MESSAGE_END.getKey() + KeyValueFacet.SEP, "message at end"), new AutocompletionText(LineDescriptionEnum.ROLE_START.getKey() + KeyValueFacet.SEP, "role at start"), new AutocompletionText(LineDescriptionEnum.ROLE_END.getKey() + KeyValueFacet.SEP, "role at end") ); } @Override public void handleLine(String line, PropertiesParserState state) { // only act on parsingFinished() when all lines are known and other first-run-facets have been resolved (e.g. fg-color) } private RelationPointHandler getRelationPoints(PropertiesParserState state) { return ((SettingsRelation) state.getSettings()).getRelationPoints(); } private void printAndUpdateIndex(DrawHandler drawer, RelationPointHandler relationPoints, PointDouble pointText, int index, String text, Point displacement, Set usedIndexes) { if (displacement != null) { pointText = new PointDouble(pointText.getX() + displacement.getX(), pointText.getY() + displacement.getY()); } printAndUpdateIndex(drawer, relationPoints, pointText, index, text, usedIndexes); } private void printAndUpdateIndex(DrawHandler drawer, RelationPointHandler relationPoints, PointDouble pointText, int index, String text, Set usedIndexes) { drawer.print(text, pointText, AlignHorizontal.LEFT); // to make sure text is printed (and therefore withing relation-element-borders, resize relation according to text relationPoints.setTextBox(index, new Rectangle(pointText.getX(), pointText.getY() - drawer.textHeightMax(), drawer.textWidth(text), drawer.textHeightMax())); usedIndexes.add(index); } @Override public void parsingFinished(PropertiesParserState state, List handledLines) { Map displacements = state.getOrInitFacetResponse(LineDescriptionPositionFacet.class, new HashMap()); RelationPointHandler relationPoints = getRelationPoints(state); DrawHandler drawer = state.getDrawer(); Set usedIndexes = new HashSet(); List middleLines = new ArrayList(); List otherLines = new ArrayList(); for (String line : handledLines) { if (LineDescriptionEnum.forString(line) == LineDescriptionEnum.MESSAGE_MIDDLE) { middleLines.add(line); } else { otherLines.add(line); } } double halfMiddleBlockHeight = middleLines.size() * drawer.textHeightMaxWithSpace() / 2; // because vertical text blocks should be centered, the half of the total text block must be subtracted for (int i = 0; i < middleLines.size(); i++) { String line = LineDescriptionUtils.replaceArrowsWithUtf8Characters(middleLines.get(i)); PointDouble pointText = LineDescriptionUtils.calcPosOfMiddleText(drawer, line, relationPoints.getMiddleLine(), i, halfMiddleBlockHeight); int index = LineDescriptionEnum.MESSAGE_MIDDLE.getIndex() + i; // middle index is increased by the amount of middle text lines printAndUpdateIndex(drawer, relationPoints, pointText, index, line, usedIndexes); } for (String line : otherLines) { LineDescriptionEnum enumVal = LineDescriptionEnum.forString(line); String[] split = line.split(KeyValueFacet.SEP, -1); String text = split[1]; if (!text.isEmpty()) { PointDouble pointText = LineDescriptionUtils.calcPosOfEndText(drawer, text, relationPoints, enumVal); printAndUpdateIndex(drawer, relationPoints, pointText, enumVal.getIndex(), text, displacements.get(enumVal.getKey()), usedIndexes); } } // all unused textboxes must be reset to default size (to make sure the relation size is correct even if LineDescriptionFacet is never called) relationPoints.resetTextBoxIndexesExcept(usedIndexes); relationPoints.resizeRectAndReposPoints(); // apply the (possible) changes now to make sure the following facets use correct coordinates } @Override public Priority getPriority() { return Priority.LOWEST; // because the middle text has no prefix, it should only apply after every other facet. also text DescriptionPositionFacet must be known before calculating the text position } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/Relation.java0000644000175000017500000001375512533641120027164 0ustar benbenpackage com.baselet.element.relation; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementId; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.NewGridElement; import com.baselet.element.UndoInformation; import com.baselet.element.facet.PropertiesParserState; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.relation.facet.RelationLineTypeFacet; import com.baselet.element.relation.facet.SettingsRelation; import com.baselet.element.relation.helper.RelationPointHandler; import com.baselet.element.relation.helper.RelationPointHolder; import com.baselet.element.relation.helper.RelationPointList; import com.baselet.element.relation.helper.RelationSelection; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.PointDoubleIndexed; import com.baselet.element.sticking.Stickable; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.polygon.NoStickingPolygonGenerator; public class Relation extends NewGridElement implements Stickable, RelationPointHolder { private RelationPointHandler relationPoints; @Override public ElementId getId() { return ElementId.Relation; } @Override protected void drawCommonContent(PropertiesParserState state) { state.setStickingPolygonGenerator(NoStickingPolygonGenerator.INSTANCE); } @Override protected void resetAndDrawMetaDrawerContent(DrawHandler drawer) { drawer.clearCache(); drawer.setBackgroundColor(ColorOwn.SELECTION_BG); // draw rectangle around whole element (basically a helper for developers to make sure the (invisible) size of the element is correct) if (SharedConfig.getInstance().isDev_mode()) { drawer.setForegroundColor(ColorOwn.TRANSPARENT); drawer.drawRectangle(0, 0, getRealSize().getWidth(), getRealSize().getHeight()); drawer.setBackgroundColor(ColorOwn.GREEN.transparency(Transparency.BACKGROUND)); relationPoints.drawSelectionSpace(drawer); } drawer.setForegroundColor(ColorOwn.SELECTION_FG); relationPoints.drawCirclesAndDragBox(drawer); } @Override public void setAdditionalAttributes(String additionalAttributes) { super.setAdditionalAttributes(additionalAttributes); RelationPointList pointList = new RelationPointList(); String[] split = additionalAttributes.split(";"); for (int i = 0; i < split.length; i += 2) { pointList.add(Double.valueOf(split[i]), Double.valueOf(split[i + 1])); } relationPoints = new RelationPointHandler(this, pointList); if (getHandler().isInitialized()) { relationPoints.resizeRectAndReposPoints(); } } @Override public String getAdditionalAttributes() { return relationPoints.toAdditionalAttributesString(); } @Override public void drag(Collection resizeDirection, int diffX, int diffY, Point mousePosBeforeDragRelative, boolean isShiftKeyDown, boolean firstDrag, StickableMap stickables, boolean undoable) { String oldAddAttr = getAdditionalAttributes(); Rectangle oldRect = getRectangle(); RelationSelection returnSelection = relationPoints.getSelectionAndMovePointsIfNecessary(pointAtDefaultZoom(mousePosBeforeDragRelative), toDefaultZoom(diffX), toDefaultZoom(diffY), firstDrag); if (returnSelection == RelationSelection.DRAG_BOX) { setLocationDifference(diffX, diffY); } if (returnSelection != RelationSelection.NOTHING) { updateModelFromText(); } if (undoable) { undoStack.add(new UndoInformation(getRectangle(), oldRect, new HashMap>(), getGridSize(), oldAddAttr, getAdditionalAttributes())); } } /** * Calculate the point for DEFAULT_ZOOM to allow ignoring zoom-level from now on */ private Point pointAtDefaultZoom(Point p) { return new Point(toDefaultZoom(p.getX()), toDefaultZoom(p.getY())); } private int toDefaultZoom(int input) { return input * SharedConstants.DEFAULT_GRID_SIZE / getGridSize(); } @Override public void dragEnd() { boolean updateNecessary = relationPoints.removeRelationPointIfOnLineBetweenNeighbourPoints(); if (updateNecessary) { updateModelFromText(); } } @Override public Set getResizeArea(int x, int y) { return new HashSet(); } @Override public boolean isSelectableOn(Point point) { Point relativePoint = new Point(point.getX() - getRectangle().getX(), point.getY() - getRectangle().getY()); boolean isSelectableOn = relationPoints.getSelection(pointAtDefaultZoom(relativePoint)) != RelationSelection.NOTHING; return isSelectableOn; } @Override public Collection getStickablePoints() { return relationPoints.getStickablePoints(); } @Override public List movePoints(List changedStickPoints) { List updatedChangedList = relationPoints.movePointAndResizeRectangle(changedStickPoints); updateModelFromText(); return updatedChangedList; } @Override public Integer getLayer() { return state.getFacetResponse(LayerFacet.class, LayerFacet.DEFAULT_VALUE_RELATION); } @Override protected Settings createSettings() { return new SettingsRelation() { @Override public RelationPointHandler getRelationPoints() { return relationPoints; } }; } @Override protected void drawError(DrawHandler drawer, String errorText) { super.drawError(drawer, errorText.replace(">>", "\\>>").replace("<<", "\\<<")); RelationLineTypeFacet.drawDefaultLineAndArrows(drawer, relationPoints); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/0000755000175000017500000000000012533641120026010 5ustar benben././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/ResizableObject.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/ResizableObject0000644000175000017500000000037612533641120031010 0ustar benbenpackage com.baselet.element.relation.helper; import com.baselet.control.basics.geom.Rectangle; public interface ResizableObject { public void setPointMinSize(int index, Rectangle rectFromCenter); public void resetPointMinSize(int index); } ././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointConstants.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointCo0000644000175000017500000000064312533641120031007 0ustar benbenpackage com.baselet.element.relation.helper; public class RelationPointConstants { public static final int DRAG_BOX_SIZE = 10; // size of the box to drag the whole relation public static final int POINT_SELECTION_RADIUS = 10; // radius of the selection circle of relation-points public static final int NEW_POINT_DISTANCE = 7; // distance from which new points can be dragged away from a relation-line } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationDrawer.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationDrawer.0000644000175000017500000002060312533641120030734 0ustar benbenpackage com.baselet.element.relation.helper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.GeometricFunctions; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.sticking.PointDoubleIndexed; public class RelationDrawer { private static final double ARROW_LENGTH = RelationPointConstants.POINT_SELECTION_RADIUS * 1.3; private static final double DIAGONAL_CROSS_LENGTH = RelationPointConstants.POINT_SELECTION_RADIUS * 0.9; private static final double BOX_SIZE = 20; public static Rectangle drawBoxArrow(DrawHandler drawer, Line line, boolean drawOnStart, String matchedText, ResizableObject resizableObject) { double oldFontsize = drawer.getFontSize(); drawer.setFontSize(12); double height = BOX_SIZE; double distance = drawer.getDistanceBorderToText(); double width = Math.max(BOX_SIZE, drawer.textWidth(matchedText) + distance * 2); PointDoubleIndexed point = (PointDoubleIndexed) line.getPoint(drawOnStart); Rectangle r = new Rectangle(point.getX() - width / 2, point.getY() - height / 2, width, height); drawer.drawRectangle(r); int arrow = 4; ColorOwn oldBgColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(drawer.getForegroundColor()); if (matchedText.equals("^")) { PointDouble start = new PointDouble(point.getX(), point.getY() - arrow); drawer.drawLines(start, new PointDouble(point.getX() + arrow, point.getY() + arrow), new PointDouble(point.getX() - arrow, point.getY() + arrow), start); } else if (matchedText.equals("<")) { PointDouble start = new PointDouble(point.getX() - arrow, point.getY()); drawer.drawLines(start, new PointDouble(point.getX() + arrow, point.getY() - arrow), new PointDouble(point.getX() + arrow, point.getY() + arrow), start); } else if (matchedText.equals(">")) { PointDouble start = new PointDouble(point.getX() + arrow, point.getY()); drawer.drawLines(start, new PointDouble(point.getX() - arrow, point.getY() - arrow), new PointDouble(point.getX() - arrow, point.getY() + arrow), start); } else if (matchedText.equals("v")) { PointDouble start = new PointDouble(point.getX() - arrow, point.getY() - arrow); drawer.drawLines(start, new PointDouble(point.getX() + arrow, point.getY() - arrow), new PointDouble(point.getX(), point.getY() + arrow), start); } else if (matchedText.equals("=")) { int dist = 2; int size = 6; drawer.drawLines(new PointDouble(point.getX() - size, point.getY() - dist), new PointDouble(point.getX() + size, point.getY() - dist), new PointDouble(point.getX(), point.getY() - size)); drawer.drawLines(new PointDouble(point.getX() + size, point.getY() + dist), new PointDouble(point.getX() - size, point.getY() + dist), new PointDouble(point.getX(), point.getY() + size)); } else { drawer.print(matchedText, new PointDouble(point.getX() - width / 2 + distance, point.getY() + drawer.textHeightMax() / 2), AlignHorizontal.LEFT); resizableObject.setPointMinSize(point.getIndex(), new Rectangle(-width / 2, -height / 2, width, height)); } drawer.setFontSize(oldFontsize); drawer.setBackgroundColor(oldBgColor); return r; } public static enum ArrowEndType { NORMAL, CLOSED, DIAMOND } public static void drawArrowToLine(DrawHandler drawer, Line line, boolean drawOnStart, ArrowEndType arrowEndType, boolean fillBody, boolean invertArrow) { drawArrowToLine(line.getPoint(drawOnStart), drawer, line, drawOnStart, arrowEndType, fillBody, invertArrow); } public static void drawArrowToLine(PointDouble point, DrawHandler drawer, Line line, boolean drawOnStart, ArrowEndType arrowEndType, boolean fillBody, boolean invertArrow) { if (invertArrow) { point = line.getPointOnLineWithDistanceFrom(drawOnStart, ARROW_LENGTH); drawOnStart = !drawOnStart; } int arrowAngle = drawOnStart ? 150 : 30; PointDouble p1 = calcPointArrow(point, line.getAngleOfSlope() - arrowAngle); PointDouble p2 = calcPointArrow(point, line.getAngleOfSlope() + arrowAngle); List points = new ArrayList(Arrays.asList(p1, point, p2)); if (arrowEndType == ArrowEndType.CLOSED) { points.add(p1); } else if (arrowEndType == ArrowEndType.DIAMOND) { double lengthDiamond = GeometricFunctions.getDistanceBetweenLineAndPoint(p1, p2, point) * 2; PointDouble pDiamond = drawOnStart ? line.getPointOnLineWithDistanceFrom(true, lengthDiamond) : line.getPointOnLineWithDistanceFrom(false, lengthDiamond); points.add(pDiamond); points.add(p1); } if (fillBody) { ColorOwn bgColor = drawer.getBackgroundColor(); drawer.setBackgroundColor(drawer.getForegroundColor()); drawer.drawLines(points); drawer.setBackgroundColor(bgColor); } else { drawer.drawLines(points); } } private static PointDouble calcPointArrow(PointDouble point, double angleTotal) { return calcPoint(point, angleTotal, ARROW_LENGTH); } private static PointDouble calcPointCross(PointDouble point, double angleTotal) { return calcPoint(point, angleTotal, DIAGONAL_CROSS_LENGTH); } private static PointDouble calcPoint(PointDouble point, double angleTotal, double length) { double x = point.x + length * Math.cos(Math.toRadians(angleTotal)); double y = point.y + length * Math.sin(Math.toRadians(angleTotal)); return new PointDouble(x, y); } public static void drawCircle(DrawHandler drawer, Line line, boolean drawOnStart, ResizableObject resizableObject, Direction openDirection, boolean drawCross) { PointDoubleIndexed point = (PointDoubleIndexed) line.getPoint(drawOnStart); if (openDirection == null) { // full circle drawer.drawCircle(point.getX(), point.getY(), RelationPointConstants.POINT_SELECTION_RADIUS); } else if (openDirection == Direction.LEFT || openDirection == Direction.RIGHT) { // interface half circle ColorOwn bg = drawer.getBackgroundColor(); drawer.setBackgroundColor(ColorOwn.TRANSPARENT); double circleRadius = RelationPointConstants.POINT_SELECTION_RADIUS * 3; Direction directionOfCircle = line.getDirectionOfLine(drawOnStart); if (directionOfCircle == Direction.RIGHT) { drawer.drawArc(point.getX(), point.getY() - circleRadius / 2, circleRadius, circleRadius, 90, 180, true); resizableObject.setPointMinSize(point.getIndex(), new Rectangle(-circleRadius / 4, -circleRadius / 2, circleRadius * 0.75, circleRadius)); } else if (directionOfCircle == Direction.DOWN) { drawer.drawArc(point.getX() - circleRadius / 2, point.getY(), circleRadius, circleRadius, 0, 180, true); resizableObject.setPointMinSize(point.getIndex(), new Rectangle(-circleRadius / 2, -circleRadius / 4, circleRadius, circleRadius * 0.75)); } else if (directionOfCircle == Direction.LEFT) { drawer.drawArc(point.getX() - circleRadius, point.getY() - circleRadius / 2, circleRadius, circleRadius, -90, 180, true); resizableObject.setPointMinSize(point.getIndex(), new Rectangle(-circleRadius / 2, -circleRadius / 2, circleRadius * 0.75, circleRadius)); } else { drawer.drawArc(point.getX() - circleRadius / 2, point.getY() - circleRadius, circleRadius, circleRadius, -180, 180, true); resizableObject.setPointMinSize(point.getIndex(), new Rectangle(-circleRadius / 2, -circleRadius / 2, circleRadius, circleRadius * 0.75)); } drawer.setBackgroundColor(bg); } if (drawCross) { double length = RelationPointConstants.POINT_SELECTION_RADIUS / 2; drawer.drawLine(point.getX() - length, point.getY(), point.getX() + length, point.getY()); drawer.drawLine(point.getX(), point.getY() - length, point.getX(), point.getY() + length); } } public static void drawDiagonalCross(DrawHandler drawer, Line line, boolean drawOnStart, ResizableObject resizableObject, Direction openDirection, boolean drawCross) { PointDouble p = line.getPointOnLineWithDistanceFrom(drawOnStart, ARROW_LENGTH); drawer.drawLines(calcPointCross(p, line.getAngleOfSlope() + 45), calcPointCross(p, line.getAngleOfSlope() - 135)); drawer.drawLines(calcPointCross(p, line.getAngleOfSlope() - 45), calcPointCross(p, line.getAngleOfSlope() + 135)); } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPoint.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPoint.j0000644000175000017500000000235012533641120030752 0ustar benbenpackage com.baselet.element.relation.helper; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.PointDoubleIndexed; public class RelationPoint { public static final Rectangle DEFAULT_SIZE = new Rectangle(-RelationPointConstants.POINT_SELECTION_RADIUS, -RelationPointConstants.POINT_SELECTION_RADIUS, RelationPointConstants.POINT_SELECTION_RADIUS * 2, RelationPointConstants.POINT_SELECTION_RADIUS * 2); private final PointDoubleIndexed point; private Rectangle size; public RelationPoint(int index, double x, double y) { this(index, x, y, DEFAULT_SIZE); } public RelationPoint(int index, double x, double y, Rectangle size) { super(); point = new PointDoubleIndexed(index, x, y); this.size = size; } public PointDoubleIndexed getPoint() { return point; } public Rectangle getSize() { return size; } public void setSize(Rectangle size) { this.size = size; } public Rectangle getSizeAbsolute() { return new Rectangle(point.getX() + size.getX(), point.getY() + size.getY(), (double) size.getWidth(), (double) size.getHeight()); } @Override public String toString() { return "RelationPoint [point=" + point + ", size=" + size + "]"; } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationSelection.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationSelecti0000644000175000017500000000020312533641120031014 0ustar benbenpackage com.baselet.element.relation.helper; public enum RelationSelection { RELATION_POINT, DRAG_BOX, LINE, NOTHING; }././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/LineDescriptionEnum.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/LineDescription0000644000175000017500000000253212533641120031030 0ustar benbenpackage com.baselet.element.relation.helper; import com.baselet.element.facet.KeyValueFacet; public enum LineDescriptionEnum { MESSAGE_START("m1", 1, true), MESSAGE_END("m2", 2, false), ROLE_START("r1", 3, true), ROLE_END("r2", 4, false), MESSAGE_MIDDLE("", 5, null) // Important: MESSAGE_MIDDLE must be the last because it can have multiple lines with indexes 5,6,7,8,... AND it matches as default if no other enum entry is valid ; private final String key; private final int index; private final Boolean start; private LineDescriptionEnum(String key, int index, Boolean start) { this.key = key; this.index = index; this.start = start; } public int getIndex() { return index; } public String getKey() { return key; } public Boolean isStart() { return start; } public static LineDescriptionEnum forString(String line) { for (LineDescriptionEnum ld : LineDescriptionEnum.values()) { if (line.startsWith(ld.key + KeyValueFacet.SEP)) { return ld; } } return LineDescriptionEnum.MESSAGE_MIDDLE; } public boolean isMessageStartOrEnd() { return this == LineDescriptionEnum.MESSAGE_START || this == LineDescriptionEnum.MESSAGE_END; } public boolean isRoleStartOrEnd() { return this == LineDescriptionEnum.ROLE_START || this == LineDescriptionEnum.ROLE_END; } }././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHandler.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHa0000644000175000017500000001564612533641120031007 0ustar benbenpackage com.baselet.element.relation.helper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.PointDoubleIndexed; public class RelationPointHandler implements ResizableObject { /** * Points of this relation (point of origin is the upper left corner of the relation element (not the drawpanel!)) */ private RelationPointList points = new RelationPointList(); private final RelationPointHolder relation; public RelationPointHandler(RelationPointHolder relation, RelationPointList points) { super(); this.relation = relation; this.points = points; } public RelationSelection getSelection(Point point) { if (isPointOverDragBox(point)) { return RelationSelection.DRAG_BOX; } else if (RelationPointHandlerUtils.getRelationPointContaining(point, points) != null) { return RelationSelection.RELATION_POINT; } else if (getLineContaining(point) != null) { return RelationSelection.LINE; } else { return RelationSelection.NOTHING; } } private PointDoubleIndexed relationPointOfCurrentDrag = null; /** * this method is basically the same as {@link #getSelection(Point)}, but also applies changes to the relationpoints * (the order of checks is the same, but they do different things, therefore they are separated) */ public RelationSelection getSelectionAndMovePointsIfNecessary(Point point, Integer diffX, Integer diffY, boolean firstDrag) { // Special case: if this is not the first drag and a relation-point is currently dragged, it has preference // Necessary to avoid changing the currently moved point if moving over another point and to avoid losing the current point if it's a new line point and the mouse is dragged very fast if (!firstDrag && relationPointOfCurrentDrag != null) { relationPointOfCurrentDrag = movePointAndResizeRectangle(relationPointOfCurrentDrag, diffX, diffY); return RelationSelection.RELATION_POINT; } // If the special case doesn't apply, forget the relationPointOfFirstDrag, because its a new first drag relationPointOfCurrentDrag = null; if (isPointOverDragBox(point)) { return RelationSelection.DRAG_BOX; } PointDoubleIndexed pointOverRelationPoint = RelationPointHandlerUtils.getRelationPointContaining(point, points); if (pointOverRelationPoint != null) { relationPointOfCurrentDrag = movePointAndResizeRectangle(pointOverRelationPoint, diffX, diffY); return RelationSelection.RELATION_POINT; } Line lineOnPoint = getLineContaining(point); if (lineOnPoint != null) { relationPointOfCurrentDrag = points.addPointOnLine(lineOnPoint, SharedUtils.realignToGridRoundToNearest(false, point.x), SharedUtils.realignToGridRoundToNearest(false, point.y)); relationPointOfCurrentDrag = movePointAndResizeRectangle(relationPointOfCurrentDrag, diffX, diffY); return RelationSelection.LINE; } return RelationSelection.NOTHING; } private boolean isPointOverDragBox(Point point) { return getDragBox().contains(point); } private Line getLineContaining(Point point) { for (Line line : points.getRelationPointLines()) { double distanceToPoint = line.getDistanceToPoint(point.toPointDouble()); if (distanceToPoint < RelationPointConstants.NEW_POINT_DISTANCE) { return line; } } return null; } public List movePointAndResizeRectangle(List changedPoints) { points.applyChangesToPoints(changedPoints); resizeRectAndReposPoints(); List updatedChangedPoint = new ArrayList(); for (PointChange c : changedPoints) { updatedChangedPoint.add(points.get(c.getIndex())); } return updatedChangedPoint; } private PointDoubleIndexed movePointAndResizeRectangle(PointDoubleIndexed point, Integer diffX, Integer diffY) { return movePointAndResizeRectangle(Arrays.asList(new PointChange(point.getIndex(), diffX, diffY))).get(0); } public void resizeRectAndReposPoints() { // now rebuild width and height of the relation, based on the new positions of the relation-points Rectangle newRect = RelationPointHandlerUtils.calculateRelationRectangleBasedOnPoints(relation.getRectangle().getUpperLeftCorner(), relation.getGridSize(), points); relation.setRectangle(newRect); // move relation points to their new position (their position is relative to the relation-position) points.moveRelationPointsAndTextSpacesByToUpperLeftCorner(); } public boolean removeRelationPointIfOnLineBetweenNeighbourPoints() { return points.removeRelationPointIfOnLineBetweenNeighbourPoints(); } // HELPER METHODS public Line getFirstLine() { return points.getFirstLine(); } public Line getMiddleLine() { return points.getMiddleLine(); } public Line getLastLine() { return points.getLastLine(); } public Collection getStickablePoints() { return points.getStickablePoints(); } public Rectangle getDragBox() { return points.getDragBox(); } // DRAW METHODS public void drawLinesBetweenPoints(DrawHandler drawer) { for (Line line : points.getRelationPointLines()) { drawer.drawLine(line); } } public void drawCirclesAndDragBox(DrawHandler drawer) { for (RelationPoint p : points.getPointHolders()) { drawer.drawCircle(p.getPoint().getX(), p.getPoint().getY(), RelationPointConstants.POINT_SELECTION_RADIUS); } drawer.drawRectangle(getDragBox()); } public String toAdditionalAttributesString() { return points.toAdditionalAttributesString(); } public void drawSelectionSpace(DrawHandler drawer) { for (RelationPoint rp : points.getPointHolders()) { drawer.drawRectangle(rp.getSizeAbsolute()); } } public void setTextBox(int index, Rectangle size) { size = SharedUtils.realignToGrid(size, true); points.setTextBox(index, size); } /** * resets all textbox indexes except those which are contained in the excludedList */ public void resetTextBoxIndexesExcept(Set excludedList) { Set unusedTextBoxIndexes = new HashSet(points.getTextBoxIndexes()); unusedTextBoxIndexes.removeAll(excludedList); for (Integer index : unusedTextBoxIndexes) { points.setTextBox(index, null); } } @Override public void setPointMinSize(int index, Rectangle size) { size = SharedUtils.realignToGrid(size, true); points.setSize(index, size); } @Override public void resetPointMinSize(int index) { points.setSize(index, RelationPoint.DEFAULT_SIZE); } @Override public String toString() { return points.toString(); } } ././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHandlerUtils.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHa0000644000175000017500000000413712533641120031000 0ustar benbenpackage com.baselet.element.relation.helper; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.element.sticking.PointDoubleIndexed; public class RelationPointHandlerUtils { static Rectangle calculateRelationRectangleBasedOnPoints(PointDouble upperLeftCorner, int gridSize, RelationPointList relationPoints) { // Calculate new Relation position and size Rectangle newSize = relationPoints.createRectangleContainingAllPointsAndTextSpace(); if (newSize == null) { throw new RuntimeException("This relation has no points: " + relationPoints); } // scale with zoom factor newSize.setBounds( newSize.getX() * gridSize / SharedConstants.DEFAULT_GRID_SIZE, newSize.getY() * gridSize / SharedConstants.DEFAULT_GRID_SIZE, newSize.getWidth() * gridSize / SharedConstants.DEFAULT_GRID_SIZE, newSize.getHeight() * gridSize / SharedConstants.DEFAULT_GRID_SIZE); // Realign new size to grid (should not be necessary as long as SELECTCIRCLERADIUS == DefaultGridSize) and add 1x gridSize to the right end (otherwise the selection-circles would change by 1px because Swing draws only to width-1 instead of width) newSize.setLocation(SharedUtils.realignTo(false, newSize.getX(), false, gridSize), SharedUtils.realignTo(false, newSize.getY(), false, gridSize)); newSize.setSize(SharedUtils.realignTo(false, newSize.getWidth(), true, gridSize) + gridSize, SharedUtils.realignTo(false, newSize.getHeight(), true, gridSize) + gridSize); // and move to correct place of Relation newSize.move(upperLeftCorner.getX().intValue(), upperLeftCorner.getY().intValue()); return newSize; } static PointDoubleIndexed getRelationPointContaining(Point point, RelationPointList points) { for (RelationPoint relationPoint : points.getPointHolders()) { if (relationPoint.getSizeAbsolute().contains(point)) { return relationPoint.getPoint(); } } return null; } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointList.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointLi0000644000175000017500000002056512533641120031017 0ustar benbenpackage com.baselet.element.relation.helper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.GeometricFunctions; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.PointDoubleIndexed; public class RelationPointList { List points = new ArrayList(); Map textBoxSpaces = new HashMap(); public void add(double x, double y) { points.add(new RelationPoint(points.size(), x, y)); } public List getPointHolders() { return Collections.unmodifiableList(points); } public PointDoubleIndexed addPointOnLine(Line line, double x, double y) { RelationPoint newPoint = null; PointDouble endOfLine = line.getStart(); for (ListIterator iter = points.listIterator(); iter.hasNext();) { PointDoubleIndexed point = iter.next().getPoint(); if (point.equals(endOfLine)) { newPoint = new RelationPoint(iter.nextIndex(), x, y); iter.add(newPoint); } } rebuildpointIndexes(); if (newPoint == null) { throw new RuntimeException("Point " + endOfLine + " not found in list " + points); } return newPoint.getPoint(); } private void rebuildpointIndexes() { List rebuiltList = new ArrayList(); for (int i = 0; i < points.size(); i++) { rebuiltList.add(new RelationPoint(i, points.get(i).getPoint().getX(), points.get(i).getPoint().getY())); } points.clear(); points.addAll(rebuiltList); } public void applyChangesToPoints(List changes) { applyPointChange(changes); // if there are only 2 points and they would overlap now (therefore the relation would have a size of 0x0px), revert the move revertChangesIfOnly2PointsOverlap(changes); } private void revertChangesIfOnly2PointsOverlap(List changes) { if (points.size() == 2 && points.get(0).getPoint().getX().equals(points.get(1).getPoint().getX()) && points.get(0).getPoint().getY().equals(points.get(1).getPoint().getY())) { List inverse = new ArrayList(); for (PointChange change : changes) { inverse.add(new PointChange(change.getIndex(), -change.getDiffX(), -change.getDiffY())); } applyPointChange(inverse); } } private void applyPointChange(List changes) { for (ListIterator iter = points.listIterator(); iter.hasNext();) { RelationPoint p = iter.next(); PointDoubleIndexed pt = p.getPoint(); for (PointChange change : changes) { if (pt.getIndex().equals(change.getIndex())) { iter.set(new RelationPoint(pt.getIndex(), pt.getX() + change.getDiffX(), pt.getY() + change.getDiffY(), p.getSize())); } } } } void moveRelationPointsAndTextSpacesByToUpperLeftCorner() { Rectangle rect = createRectangleContainingAllPointsAndTextSpace(); int displacementX = SharedUtils.realignToGrid(false, rect.getX(), false); int displacementY = SharedUtils.realignToGrid(false, rect.getY(), false); moveRelationPointsAndTextSpacesBy(-displacementX, -displacementY); } void moveRelationPointsAndTextSpacesBy(int displacementX, int displacementY) { for (ListIterator iter = points.listIterator(); iter.hasNext();) { RelationPoint p = iter.next(); iter.set(new RelationPoint(p.getPoint().getIndex(), p.getPoint().getX() + displacementX, p.getPoint().getY() + displacementY, p.getSize())); // If points are off the grid they can be realigned here (use the following 2 lines instead of move()) // p.setX(SharedUtils.realignTo(true, p.getX()-displacementX, false, SharedConstants.DEFAULT_GRID_SIZE)); // p.setY(SharedUtils.realignTo(true, p.getY()-displacementY, false, SharedConstants.DEFAULT_GRID_SIZE)); } for (Entry textSpace : textBoxSpaces.entrySet()) { Rectangle old = textSpace.getValue(); textSpace.setValue(new Rectangle(old.getX() + displacementX, old.getY() + displacementY, old.getWidth(), old.getHeight())); } } public boolean removeRelationPointIfOnLineBetweenNeighbourPoints() { boolean updateNecessary = false; if (points.size() > 2) { ListIterator iter = points.listIterator(); PointDoubleIndexed leftNeighbour = iter.next().getPoint(); PointDoubleIndexed pointToCheck = iter.next().getPoint(); while (iter.hasNext()) { PointDoubleIndexed rightNeighbour = iter.next().getPoint(); // if a point lies on the line between its 2 neighbourpoints, it will be removed if (GeometricFunctions.getDistanceBetweenLineAndPoint(leftNeighbour, rightNeighbour, pointToCheck) < 5) { updateNecessary = true; iter.previous(); iter.previous(); iter.remove(); pointToCheck = iter.next().getPoint(); } else { leftNeighbour = pointToCheck; pointToCheck = rightNeighbour; } } } if (updateNecessary) { rebuildpointIndexes(); } return updateNecessary; } public List getRelationPointLines() { List lines = new ArrayList(); for (int i = 1; i < points.size(); i++) { lines.add(new Line(points.get(i - 1).getPoint(), points.get(i).getPoint())); } return lines; } public Line getFirstLine() { return new Line(points.get(0).getPoint(), points.get(1).getPoint()); } public Line getMiddleLine() { PointDoubleIndexed begin = points.get(points.size() / 2).getPoint(); PointDoubleIndexed end = points.get(points.size() / 2 - 1).getPoint(); return new Line(begin, end); } public Line getLastLine() { return new Line(points.get(points.size() - 2).getPoint(), points.get(points.size() - 1).getPoint()); } public Collection getStickablePoints() { return Arrays.asList(points.get(0).getPoint(), points.get(points.size() - 1).getPoint()); } public Rectangle getDragBox() { PointDouble center = getMiddleLine().getCenter(); double size = RelationPointConstants.DRAG_BOX_SIZE / 2; Rectangle rectangle = new Rectangle(center.x - size, center.y - size, size * 2, size * 2); return rectangle; } public String toAdditionalAttributesString() { StringBuilder sb = new StringBuilder(""); for (RelationPoint p : points) { sb.append(p.getPoint().getX()).append(";").append(p.getPoint().getY()).append(";"); } if (sb.length() > 0) { sb.setLength(sb.length() - 1); } return sb.toString(); } @Override public String toString() { return "Relationpoints: " + SharedUtils.listToString(",", points); } public PointDoubleIndexed get(int index) { return points.get(index).getPoint(); } public void setSize(int index, Rectangle size) { for (RelationPoint p : points) { if (p.getPoint().getIndex() == index) { p.setSize(size); return; } } throw new RuntimeException("Unknown Point Index " + index); } public void setTextBox(int index, Rectangle rect) { if (rect == null) { textBoxSpaces.remove(index); } else { textBoxSpaces.put(index, rect); } } public Set getTextBoxIndexes() { return textBoxSpaces.keySet(); } public Rectangle createRectangleContainingAllPointsAndTextSpace() { Rectangle rectangleContainingAllPointsAndTextSpace = null; for (RelationPoint p : points) { rectangleContainingAllPointsAndTextSpace = addWithNullCheck(rectangleContainingAllPointsAndTextSpace, p.getSizeAbsolute()); } for (Rectangle textSpace : textBoxSpaces.values()) { rectangleContainingAllPointsAndTextSpace = addWithNullCheck(rectangleContainingAllPointsAndTextSpace, textSpace); } return rectangleContainingAllPointsAndTextSpace; } private Rectangle addWithNullCheck(Rectangle rectangleContainingAllPointsAndTextSpace, Rectangle rectangle) { if (rectangleContainingAllPointsAndTextSpace == null) { rectangleContainingAllPointsAndTextSpace = rectangle; } else { rectangleContainingAllPointsAndTextSpace.merge(rectangle); } return rectangleContainingAllPointsAndTextSpace; } } ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHolder.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/relation/helper/RelationPointHo0000644000175000017500000000035212533641120031011 0ustar benbenpackage com.baselet.element.relation.helper; import com.baselet.control.basics.geom.Rectangle; public interface RelationPointHolder { Rectangle getRectangle(); void setRectangle(Rectangle rect); int getGridSize(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/GridElementUtils.java0000644000175000017500000000131112533641120026773 0ustar benbenpackage com.baselet.element; import java.util.Collection; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.interfaces.GridElement; public class GridElementUtils { public static Rectangle getGridElementsRectangle(Collection gridElements) { int x = Integer.MAX_VALUE; int y = Integer.MAX_VALUE; int x2 = Integer.MIN_VALUE; int y2 = Integer.MIN_VALUE; for (GridElement ge : gridElements) { x = Math.min(ge.getRectangle().getX(), x); y = Math.min(ge.getRectangle().getY(), y); x2 = Math.max(ge.getRectangle().getX2(), x2); y2 = Math.max(ge.getRectangle().getY2(), y2); } return new Rectangle(x, y, x2 - x, y2 - y); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/Selector.java0000644000175000017500000001205012533641120025335 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.GridElement; public abstract class Selector { private void selectHelper(boolean applyAfterAction, Collection elements) { for (GridElement e : expand(elements)) { if (!getSelectedElements().contains(e)) { getSelectedElements().add(e); doAfterSelect(e); } } if (applyAfterAction) { doAfterSelectionChanged(); } } private void deselectHelper(boolean applyAfterAction, Collection elements) { for (GridElement e : expand(elements)) { Iterator iter = getSelectedElements().iterator(); while (iter.hasNext()) { if (iter.next().equals(e)) { iter.remove(); doAfterDeselect(e); } } } if (applyAfterAction) { doAfterSelectionChanged(); } } private List expand(Collection elements) { Map> map = Selector.createGroupElementMap(getAllElements()); List elemenentsWithGroups = new ArrayList(); // add grouped elements BEFORE the really selected elements, to make sure the last element stays the same (because its content will be shown in the property panel) for (GridElement e : elements) { if (e.getGroup() != null) { Collection set = map.get(e.getGroup()); if (set != null) { // TODO set can be null in standalone version because getAllElements is empty (eg if grouped elements are selected when diagram is closed) for (GridElement g : set) { if (g != e) { elemenentsWithGroups.add(g); } } } } } elemenentsWithGroups.addAll(elements); return elemenentsWithGroups; } public void select(GridElement element) { select(Arrays.asList(element)); } public void deselect(GridElement element) { deselect(Arrays.asList(element)); } public abstract List getSelectedElements(); public boolean isSelected(GridElement ge) { return getSelectedElements().contains(ge); } public boolean isSelectedOnly(GridElement ge) { return getSelectedElements().size() == 1 && isSelected(ge); } public void selectOnly(GridElement element) { selectOnly(Arrays.asList(element)); } public void selectOnly(Collection elements) { deselectHelper(false, getSelectedElements()); selectHelper(true, elements); } public void select(Collection elements) { selectHelper(true, elements); } public void deselect(Collection elements) { deselectHelper(true, elements); } public void deselectAll() { deselect(getSelectedElements()); } public void deselectAllWithoutAfterAction() { deselectHelper(false, getSelectedElements()); } public void doAfterDeselect(GridElement e) { e.getComponent().afterModelUpdate(); } public void doAfterSelectionChanged() { // hook method } public void doAfterSelect(GridElement e) { e.getComponent().afterModelUpdate(); } public void moveToLastPosInList(GridElement element) { List elements = getSelectedElements(); elements.remove(element); elements.add(element); } public Integer getUnusedGroup() { return getUnusedGroupId(createGroupElementMap(getAllElements()).keySet()); } public abstract List getAllElements(); public static void replaceGroupsWithNewGroups(Collection elements, Selector selector) { Set usedIds = new HashSet(createGroupElementMap(selector.getAllElements()).keySet()); Map> groupedElements = createGroupElementMap(elements); for (Entry> entry : groupedElements.entrySet()) { Integer unusedId = getUnusedGroupId(usedIds); usedIds.add(unusedId); for (GridElement e : entry.getValue()) { e.setProperty(GroupFacet.KEY, unusedId); } } } public static Integer getUnusedGroupId(Collection usedGroups) { Integer newGroup; if (usedGroups.isEmpty()) { newGroup = 1; } else { newGroup = Collections.max(usedGroups) + 1; } return newGroup; } public static Map> createGroupElementMap(Collection elements) { Map> returnmap = new HashMap>(); for (GridElement e : elements) { if (e.getGroup() != null) { Collection elementsWithGroup = returnmap.get(e.getGroup()); if (elementsWithGroup == null) { elementsWithGroup = new ArrayList(); returnmap.put(e.getGroup(), elementsWithGroup); } elementsWithGroup.add(e); } } return returnmap; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/PropertiesParser.java0000644000175000017500000001035112533641120027070 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.PropertiesParserState; /** * The PropertiesParser analyzes the Properties and the Facets of a GridElement and handles AUTORESIZE * The Facets typically manipulates the DrawHandler state by executing the drawing methods (e.g. printing the main-text of the element, transforming -- to a horizontal line, ...) * * A summary of the process is the following: * 1. Do a complete parser run (without drawing anything) to calculate the textblock height and possibly start the AUTORESIZE calculation. * 2. The First-Run Facets get parsed and applied in order of their PriorityEnum value (this reduces the size of the remaining properties for the Second Run) * 3. The common content of the element is drawn (e.g. the border) (therefore this must happen AFTER parsing the First-Run Facets because they can change the bg-color and so on) * 4. The remaining properties are parsed and the Second-Run Facets are applied. */ public class PropertiesParser { public static void parsePropertiesAndHandleFacets(NewGridElement element, PropertiesParserState state) { List propertiesText = element.getPanelAttributesAsList(); doPreparsing(element, state, propertiesText); // at first handle autoresize (which possibly changes elementsize) and calc the textblock size parseFacets(element, state, propertiesText, true); } private static void doPreparsing(NewGridElement element, PropertiesParserState state, List propertiesText) { state.resetValues(element.getRealSize(), state.getTotalTextBlockHeight(), false); // assume certain values and disable drawing for the preparsing step parseFacets(element, state, propertiesText, false); if (state.getElementStyle() == ElementStyle.AUTORESIZE) { // only in case of autoresize element, calculate the elementsize double width = state.getCalculatedElementWidth(); double height = state.getTextPrintPosition() - state.getDrawer().textHeightMax(); // subtract 1xtextheight to avoid making element too high (because the print-text pos is always on the bottom) element.handleAutoresize(new DimensionDouble(width, height), state.getAlignment().getHorizontal()); } double textblockHeight = state.getTextPrintPosition() - state.getBuffer().getTop(); state.resetValues(element.getRealSize(), textblockHeight, true); // now that the element size and textblock height is known, the state is reset once again with enabled drawing } private static void parseFacets(NewGridElement element, PropertiesParserState state, List propertiesText, boolean drawMetaDrawer) { List propertiesAfterFirstRun = parseFacets(state.getSettings().getFacetsForFirstRun(), propertiesText, state); // must be before element.drawCommonContent (because bg=... and other settings are set here) element.resetMetaDrawerAndDrawCommonContent(state, drawMetaDrawer); // draw common content like border around classes parseFacets(state.getSettings().getFacetsForSecondRun(), propertiesAfterFirstRun, state); // iterate over propertiestext and draw text and resolve second-run facets } private static List parseFacets(List facets, List properties, PropertiesParserState state) { Map> facetUsageMap = new HashMap>(); for (Facet f : facets) { // at parsing start every facet has an empty usage list facetUsageMap.put(f, new ArrayList()); } List unusedProperties = new ArrayList(properties); for (Iterator iter = unusedProperties.iterator(); iter.hasNext();) { String line = iter.next(); for (Facet f : facets) { if (f.checkStart(line, state)) { f.handleLine(line, state); facetUsageMap.get(f).add(line); iter.remove(); break; // once a facet has consumed a line, no other facet can } } } for (Facet f : facets) { f.parsingFinished(state, facetUsageMap.get(f)); } return unusedProperties; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/draw/0000755000175000017500000000000012533641120023651 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/draw/DrawHelper.java0000644000175000017500000000477312533641120026564 0ustar benbenpackage com.baselet.element.draw; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.diagram.draw.DrawHandler; public class DrawHelper { public static List drawPackage(DrawHandler drawer, double upperLeftX, double upperLeftY, double titleHeight, double titleWidth, double fullHeight, double fullWidth) { PointDouble start = new PointDouble(upperLeftX, upperLeftY); List points = Arrays.asList( start, new PointDouble(upperLeftX + titleWidth, upperLeftY), new PointDouble(upperLeftX + titleWidth, upperLeftY + titleHeight), new PointDouble(upperLeftX + fullWidth, upperLeftY + titleHeight), new PointDouble(upperLeftX + fullWidth, upperLeftY + fullHeight), new PointDouble(upperLeftX, upperLeftY + fullHeight), start ); drawer.drawLines(points); drawer.drawLines(new PointDouble(upperLeftX, upperLeftY + titleHeight), new PointDouble(upperLeftX + titleWidth, upperLeftY + titleHeight)); return points; } public static void drawActor(DrawHandler drawer, int hCenter, int yTop, double dimension) { drawer.drawCircle(hCenter, yTop + DrawHelper.headRadius(dimension), DrawHelper.headRadius(dimension)); // Head drawer.drawLine(hCenter - DrawHelper.armLength(dimension), yTop + DrawHelper.armHeight(dimension), hCenter + DrawHelper.armLength(dimension), yTop + DrawHelper.armHeight(dimension)); // Arms drawer.drawLine(hCenter, yTop + DrawHelper.headRadius(dimension) * 2, hCenter, yTop + DrawHelper.headToBodyLength(dimension)); // Body drawer.drawLine(hCenter, yTop + DrawHelper.headToBodyLength(dimension), hCenter - DrawHelper.legSpan(dimension), yTop + DrawHelper.headToLegLength(dimension)); // Legs drawer.drawLine(hCenter, yTop + DrawHelper.headToBodyLength(dimension), hCenter + DrawHelper.legSpan(dimension), yTop + DrawHelper.headToLegLength(dimension)); // Legs } public static double headToLegLength(double dimension) { return legSpan(dimension) * 2 + headToBodyLength(dimension); } private static double legSpan(double dimension) { return dimension; } private static double headToBodyLength(double dimension) { return dimension * 2 + headRadius(dimension) * 2; } private static double armHeight(double dimension) { return armLength(dimension); } public static double armLength(double dimension) { return dimension * 1.5; } private static double headRadius(double dimension) { return dimension / 2; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/0000755000175000017500000000000012533641120024554 5ustar benben././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsManualresizeCenter.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsManualresizeCe0000644000175000017500000000112312533641120031124 0ustar benbenpackage com.baselet.element.settings; import java.util.List; import com.baselet.control.enums.AlignVertical; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; public abstract class SettingsManualresizeCenter extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.SIMPLE; } @Override protected List createFacets() { return Settings.MANUALRESIZE; } @Override public AlignVertical getVAlign() { return AlignVertical.CENTER; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsNoText.java0000644000175000017500000000065612533641120030370 0ustar benbenpackage com.baselet.element.settings; import java.util.List; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; public class SettingsNoText extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.SIMPLE; } @Override protected List createFacets() { return Settings.NOTEXT; } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsAutoresize.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsAutoresize.jav0000644000175000017500000000067212533641120031136 0ustar benbenpackage com.baselet.element.settings; import java.util.List; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; public class SettingsAutoresize extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.AUTORESIZE; } @Override protected List createFacets() { return Settings.AUTORESIZE; } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsManualResizeTop.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsManualResizeTo0000644000175000017500000000070612533641120031125 0ustar benbenpackage com.baselet.element.settings; import java.util.List; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; public abstract class SettingsManualResizeTop extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.SIMPLE; } @Override protected List createFacets() { return Settings.MANUALRESIZE; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/settings/SettingsText.java0000644000175000017500000000124412533641120030065 0ustar benbenpackage com.baselet.element.settings; import java.util.List; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.ElementStyle; import com.baselet.element.facet.Facet; import com.baselet.element.facet.Settings; import com.baselet.element.facet.common.SeparatorLineFacet; public class SettingsText extends Settings { @Override public ElementStyle getElementStyle() { return ElementStyle.WORDWRAP; } @Override protected List createFacets() { return listOf(Settings.MANUALRESIZE, SeparatorLineFacet.INSTANCE); } @Override public AlignHorizontal getHAlign() { return AlignHorizontal.LEFT; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/0000755000175000017500000000000012533641120024527 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/Stickable.java0000644000175000017500000000054112533641120027273 0ustar benbenpackage com.baselet.element.sticking; import java.util.Collection; import java.util.List; import com.baselet.control.basics.geom.Rectangle; public interface Stickable { Collection getStickablePoints(); List movePoints(List changedStickPoints); Rectangle getRealRectangle(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/StickingPolygon.java0000644000175000017500000001064312533641120030521 0ustar benbenpackage com.baselet.element.sticking; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Vector; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; public class StickingPolygon { public static class StickLine extends Line { StickLine(PointDouble p1, PointDouble p2) { super(p1, p2); } // calculates the difference between this line and the other line at the specified x or y coordinate (whichever fits better) public PointDouble diffToLine(StickLine s, int inX, int inY) { double x = 0; double y = 0; if (getEnd().x.equals(getStart().x)) { // AB: Fixed: use s.getStart().x instead of getStart().x x = s.getStart().x - (s.getEnd().x - s.getStart().x) - inX; // mitte der neuen linie if (s.getEnd().x.equals(s.getStart().x)) { // vertical lines - no y difference except the line is at an end y = 0; if (s.getStart().y > s.getEnd().y) { if (s.getStart().y < inY) { y = s.getStart().y - inY; } else if (s.getEnd().y > inY) { y = s.getEnd().y - inY; } } else { if (s.getEnd().y < inY) { y = s.getEnd().y - inY; } else if (s.getStart().y > inY) { y = s.getStart().y - inY; } } return new PointDouble(x, y); } } else { x = (inX - getStart().x) * (s.getEnd().x - s.getStart().x) / (getEnd().x - getStart().x) + s.getStart().x - inX; } if (getEnd().y.equals(getStart().y)) { // AB: Fixed: use s.getStart().x instead of getStart().x y = s.getStart().y - (s.getEnd().y - s.getStart().y) - inY; if (s.getEnd().y.equals(s.getStart().y)) { // horizontal lines - no x difference except the line is at an end x = 0; if (s.getStart().x > s.getEnd().x) { if (s.getStart().x < inX) { x = s.getStart().x - inX; } else if (s.getEnd().x > inX) { x = s.getEnd().x - inX; } } else { if (s.getEnd().x < inX) { x = s.getEnd().x - inX; } else if (s.getStart().x > inX) { x = s.getStart().x - inX; } } } } else { y = (inY - getStart().y) * (s.getEnd().y - s.getStart().y) / (getEnd().y - getStart().y) + s.getStart().y - inY; } return new PointDouble(x, y); } public boolean isConnected(PointDouble p, int maxDistance) { double distance = getDistanceToPoint(p); return distance < maxDistance; } } private final Vector stick = new Vector(); private PointDouble lastpoint = null; private PointDouble firstpoint = null; private final int elementX; private final int elementY; // store all points for the copyZoomed() method private final List allPoints = new ArrayList(); public StickingPolygon(int elementX, int elementY) { this.elementX = elementX; this.elementY = elementY; } public void addPoint(List points) { for (PointDouble p : points) { addPoint(p.getX(), p.getY()); } } public void addPoint(double x, double y) { PointDouble p = new PointDouble(elementX + x, elementY + y); allPoints.add(p); if (firstpoint == null) { firstpoint = p; } else { stick.add(new StickLine(lastpoint, p)); } lastpoint = p; } public void addPoint(int x, int y, boolean connectToFirst) { this.addPoint(x, y); if (connectToFirst) { allPoints.add(firstpoint); stick.add(new StickLine(lastpoint, firstpoint)); } } public void addRectangle(int x, int y, int width, int height) { addPoint(x, y); addPoint(x + width, y); addPoint(x + width, y + height); addPoint(x, y + height, true); } public void addRectangle(Rectangle rect) { addRectangle(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); } public StickLine getLine(int index) { return stick.get(index); } public Vector getStickLines() { return stick; } public int isConnected(PointDouble p, int gridSize) { int con = -1; for (int i = 0; i < stick.size(); i++) { if (stick.get(i).isConnected(p, gridSize)) { return i; } } return con; } @Override public String toString() { return "StickingPolygon [stick=" + Arrays.toString(stick.toArray(new StickLine[stick.size()])) + "]"; } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/PointDoubleIndexed.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/PointDoubleIndexed.jav0000644000175000017500000000207112533641120030756 0ustar benbenpackage com.baselet.element.sticking; import com.baselet.control.basics.geom.PointDouble; public class PointDoubleIndexed extends PointDouble { private final Integer index; public PointDoubleIndexed(Integer index, double x, double y) { super(x, y); this.index = index; } public Integer getIndex() { return index; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (index == null ? 0 : index.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } PointDoubleIndexed other = (PointDoubleIndexed) obj; if (index == null) { if (other.index != null) { return false; } } else if (!index.equals(other.index)) { return false; } return true; } @Override public String toString() { return "p(i=" + index + " x=" + x + " y=" + y + ")"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/0000755000175000017500000000000012533641120026216 5ustar benben././@LongLink0000644000000000000000000000017200000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/SimpleStickingPolygonGenerator.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/SimpleSticking0000644000175000017500000000113112533641120031062 0ustar benbenpackage com.baselet.element.sticking.polygon; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.StickingPolygon; public class SimpleStickingPolygonGenerator implements StickingPolygonGenerator { public static final SimpleStickingPolygonGenerator INSTANCE = new SimpleStickingPolygonGenerator(); private SimpleStickingPolygonGenerator() {} @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addRectangle(0, 0, rect.width, rect.height); return p; } } ././@LongLink0000644000000000000000000000017700000000000011610 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/PointDoubleStickingPolygonGenerator.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/PointDoubleSti0000644000175000017500000000122412533641120031044 0ustar benbenpackage com.baselet.element.sticking.polygon; import java.util.List; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.StickingPolygon; public class PointDoubleStickingPolygonGenerator implements StickingPolygonGenerator { private List points; public PointDoubleStickingPolygonGenerator(List points) { super(); this.points = points; } @Override public StickingPolygon generateStickingBorder(Rectangle rect) { StickingPolygon p = new StickingPolygon(rect.x, rect.y); p.addPoint(points); return p; } } ././@LongLink0000644000000000000000000000016600000000000011606 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/NoStickingPolygonGenerator.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/NoStickingPoly0000644000175000017500000000077512533641120031066 0ustar benbenpackage com.baselet.element.sticking.polygon; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.StickingPolygon; public class NoStickingPolygonGenerator implements StickingPolygonGenerator { public static final NoStickingPolygonGenerator INSTANCE = new NoStickingPolygonGenerator(); private NoStickingPolygonGenerator() {} @Override public StickingPolygon generateStickingBorder(Rectangle rect) { return new StickingPolygon(rect.x, rect.y); } } ././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/StickingPolygonGenerator.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/polygon/StickingPolygo0000644000175000017500000000041512533641120031106 0ustar benbenpackage com.baselet.element.sticking.polygon; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.sticking.StickingPolygon; public interface StickingPolygonGenerator { public StickingPolygon generateStickingBorder(Rectangle rect); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/StickableMap.java0000644000175000017500000000607312533641120027737 0ustar benbenpackage com.baselet.element.sticking; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.baselet.control.SharedUtils; public class StickableMap { public static final StickableMap EMPTY_MAP = new StickableMap(); /** * only the index of sticking points is stored here, because the position of the sticking point can change inbetween * (eg: a relation with description text which moves around and needs space on any side of the relation, therefore resizing and repositioning the relation) */ Map> stickingIndexMap = new HashMap>(); public StickableMap() {} public boolean equalsMap(StickableMap other) { return checkMapsEqual(stickingIndexMap, other.stickingIndexMap); } private static boolean checkMapsEqual(Map> mapA, Map> mapB) { if (!containSameElements(mapA.keySet(), mapB.keySet())) { return false; // keys are not equal } for (Entry> entry : mapA.entrySet()) { List setA = entry.getValue(); List setB = mapB.get(entry.getKey()); if (!containSameElements(setA, setB)) { return false; // values for this key are not equal } } return true; // all keys and values are equal } private static boolean containSameElements(Collection setA, Collection setB) { return setA.containsAll(setB) && setB.containsAll(setA); } public boolean isEmpty() { for (List valueList : stickingIndexMap.values()) { if (!valueList.isEmpty()) { return false; } } return true; } public void add(Stickable stickable, PointDoubleIndexed p) { List points = stickingIndexMap.get(stickable); if (points == null) { points = new ArrayList(); stickingIndexMap.put(stickable, points); } points.add(p.getIndex()); } public Set getStickables() { return stickingIndexMap.keySet(); } public List getStickablePoints(Stickable stickable) { // get the points of all indexes which stick (must be done now and not cached, because every info of the points except the index can change! List stickingIndexes = stickingIndexMap.get(stickable); List returnList = new ArrayList(); for (PointDoubleIndexed p : stickable.getStickablePoints()) { if (stickingIndexes.contains(p.getIndex())) { returnList.add(p); } } return returnList; } public void setStickablePoints(Stickable stickable, List updatedChangedPoints) { List indexList = new ArrayList(); for (PointDoubleIndexed p : updatedChangedPoints) { indexList.add(p.getIndex()); } stickingIndexMap.put(stickable, indexList); } @Override public String toString() { return "StickableMap [map=" + SharedUtils.mapToString("\n", ",", stickingIndexMap) + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/StickLineChange.java0000644000175000017500000000106012533641120030362 0ustar benbenpackage com.baselet.element.sticking; import com.baselet.element.sticking.StickingPolygon.StickLine; public class StickLineChange { StickLine oldLine; StickLine newLine; public StickLineChange(StickLine oldLine, StickLine newLine) { super(); this.oldLine = oldLine; this.newLine = newLine; } public StickLine getNew() { return newLine; } public StickLine getOld() { return oldLine; } @Override public String toString() { return "StickLineChange [oldLine=" + oldLine + ", newLine=" + newLine + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/Stickables.java0000644000175000017500000002126612533641120027465 0ustar benbenpackage com.baselet.element.sticking; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.constants.SharedConstants; import com.baselet.element.sticking.StickingPolygon.StickLine; public class Stickables { private static Logger log = Logger.getLogger(Stickables.class); public static StickableMap getStickingPointsWhichAreConnectedToStickingPolygon(StickingPolygon oldStickingPolygon, Collection stickables) { int maxDistance = SharedConstants.DEFAULT_GRID_SIZE - 1; // because stickables is always calculated at 10px gridsize, the maxdistance for sticking is 9px (this tolerance is important for diagonal stickinglines like the UseCase has, otherwise 0px tolerance should always work if the stickingLineEnd is always on the exact same Point as the stickingpolygon) log.debug("Polygon to check: " + oldStickingPolygon); StickableMap returnMap = new StickableMap(); for (final Stickable stickable : stickables) { for (final PointDoubleIndexed p : stickable.getStickablePoints()) { PointDouble absolutePointPosition = getAbsolutePosition(stickable, p); for (StickLine sl : oldStickingPolygon.getStickLines()) { log.trace("CHECK " + sl + "/" + absolutePointPosition + "/" + maxDistance); if (sl.isConnected(absolutePointPosition, maxDistance)) { returnMap.add(stickable, p); } } } } return returnMap; } public static Map> moveStickPointsBasedOnPolygonChanges(StickingPolygon oldStickingPolygon, StickingPolygon newStickingPolygon, StickableMap stickablePointsToCheck, int maxDistance) { // the first drag determines which stickables and which points of them will stick (eg: moving through other relations should NOT "collect" their stickingpoints) if (oldStickingPolygon == null || stickablePointsToCheck == null || stickablePointsToCheck.isEmpty()) { return Collections.emptyMap(); // if element has no stickingPolygon or no stickables located on it, nothing has to be checked } // determine which sticklines have changed and only check sticks for them List changedStickLines = getChangedStickLines(oldStickingPolygon, newStickingPolygon); // go through all stickpoints and handle the stickline-change Map> changeList = new HashMap>(); for (final Stickable stickable : stickablePointsToCheck.getStickables()) { List calculatedStickingPointChanges = calculateStickingPointChanges(stickable, stickablePointsToCheck.getStickablePoints(stickable), changedStickLines, maxDistance); if (!calculatedStickingPointChanges.isEmpty()) { changeList.put(stickable, calculatedStickingPointChanges); } } applyChanges(changeList, stickablePointsToCheck); return changeList; } public static void applyChanges(Map> changeList, StickableMap stickablePointsToCheck) { for (Entry> entry : changeList.entrySet()) { Stickable stickable = entry.getKey(); List updatedChangedPoints = stickable.movePoints(entry.getValue()); if (stickablePointsToCheck != null) { stickablePointsToCheck.setStickablePoints(stickable, updatedChangedPoints); } } } private static List getChangedStickLines(StickingPolygon oldStickingPolygon, StickingPolygon newStickingPolygon) { List changedStickLines = new ArrayList(); Iterator oldLineIter = oldStickingPolygon.getStickLines().iterator(); Iterator newLineIter = newStickingPolygon.getStickLines().iterator(); while (oldLineIter.hasNext()) { StickLine oldLine = oldLineIter.next(); StickLine newLine = newLineIter.next(); if (!oldLine.equals(newLine)) { changedStickLines.add(new StickLineChange(oldLine, newLine)); } } return changedStickLines; } private static List calculateStickingPointChanges(Stickable stickable, List stickablePoints, List changedStickLines, int maxDistance) { List changedPoints = new ArrayList(); for (PointDoubleIndexed stickablePoint : stickablePoints) { PointDouble absolutePosOfStickablePoint = getAbsolutePosition(stickable, stickablePoint); StickLineChange relevantStickline = getNearestStickLineChangeWhichWillChangeTheStickPoint(changedStickLines, absolutePosOfStickablePoint, maxDistance); if (relevantStickline != null) { PointChange changedPoint = calcPointDiffBasedOnStickLineChange(stickablePoint.getIndex(), absolutePosOfStickablePoint, relevantStickline); if (changedPoint.getDiffX() != 0 || changedPoint.getDiffY() != 0) { changedPoints.add(changedPoint); } } } return changedPoints; } static PointChange calcPointDiffBasedOnStickLineChange(Integer index, PointDouble stickablePoint, StickLineChange stickline) { StickLine oldLine = stickline.getOld(); StickLine newLine = stickline.getNew(); int diffX = 0; int diffY = 0; if (newLine.getDirectionOfLine(true).isHorizontal()) { diffY = newLine.getStart().getY().intValue() - oldLine.getStart().getY().intValue(); diffX = calcOtherCoordinate(stickablePoint, oldLine, newLine, 0, diffY).getX().intValue(); } else { diffX = newLine.getStart().getX().intValue() - oldLine.getStart().getX().intValue(); diffY = calcOtherCoordinate(stickablePoint, oldLine, newLine, diffX, 0).getY().intValue(); } return new PointChange(index, diffX, diffY); } private static PointDouble calcOtherCoordinate(PointDouble stickablePoint, StickLine oldLine, StickLine newLine, int diffX, int diffY) { PointDouble stickablePointWithDiff = new PointDouble(stickablePoint.getX() + diffX, stickablePoint.getY() + diffY); // if the line length has not changed, the point must be moved like the line if (oldLine.getLength() == newLine.getLength()) { return new PointDouble(newLine.getStart().getX().intValue() - oldLine.getStart().getX().intValue(), newLine.getStart().getY().intValue() - oldLine.getStart().getY().intValue()); } // if line length has changed and the changed stickablePoint is not on line anymore, it will move to the nearest newLineend (start or end of line) else if (newLine.getDistanceToPoint(stickablePointWithDiff) > 1) { PointDouble point; if (newLine.getStart().distance(stickablePointWithDiff) < newLine.getEnd().distance(stickablePointWithDiff)) { point = newLine.getStart(); } else { point = newLine.getEnd(); } return new PointDouble(point.getX() - stickablePoint.getX(), point.getY() - stickablePoint.getY()); } return new PointDouble(0, 0); } private static StickLineChange getNearestStickLineChangeWhichWillChangeTheStickPoint(List changedStickLines, PointDouble absolutePositionOfStickablePoint, int maxDistance) { Double lowestDistance = null; StickLineChange changeMatchingLowestDistance = null; for (StickLineChange change : changedStickLines) { double distance = change.getOld().getDistanceToPoint(absolutePositionOfStickablePoint); // update best match if this distance is in range and better than the old best match if (distance < maxDistance && (lowestDistance == null || distance < lowestDistance)) { // if distance to start end end of the stickable line has changed, move the stickable point (avoids unwanted moves (eg stickablepoint in middle and resizing top or bottom -> no move necessary)) // if ((Line.distanceBetweenTwoPoints(change.getOld().getStart(), absolutePositionOfStickablePoint) != Line.distanceBetweenTwoPoints(change.getNew().getStart(), absolutePositionOfStickablePoint)) && // (Line.distanceBetweenTwoPoints(change.getOld().getEnd(), absolutePositionOfStickablePoint) != Line.distanceBetweenTwoPoints(change.getNew().getEnd(), absolutePositionOfStickablePoint))) { lowestDistance = distance; changeMatchingLowestDistance = change; // } } } return changeMatchingLowestDistance; } private static PointDouble getAbsolutePosition(Stickable stickable, PointDouble pd) { // the points are located relative to the upper left corner of the relation, therefore add this corner to have it located to the upper left corner of the diagram int x = stickable.getRealRectangle().getX() + pd.getX().intValue(); int y = stickable.getRealRectangle().getY() + pd.getY().intValue(); return new PointDouble(x, y); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/element/sticking/PointChange.java0000644000175000017500000000112112533641120027564 0ustar benbenpackage com.baselet.element.sticking; public class PointChange { private final Integer index; private final int diffX; private final int diffY; public PointChange(Integer index, int diffX, int diffY) { super(); this.index = index; this.diffX = diffX; this.diffY = diffY; } public Integer getIndex() { return index; } public int getDiffX() { return diffX; } public int getDiffY() { return diffY; } @Override public String toString() { return "PointChange [index=" + index + ", diffX=" + diffX + ", diffY=" + diffY + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/0000755000175000017500000000000012533641120022743 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/constants/0000755000175000017500000000000012533641120024757 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/constants/FacetConstants.java0000644000175000017500000000037312533641120030544 0ustar benbenpackage com.baselet.control.constants; public class FacetConstants { public static final String BACKGROUND_COLOR_KEY = "bg"; public static final String FOREGROUND_COLOR_KEY = "fg"; public static final double LINE_WIDTH_DEFAULT = 1.0; } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/constants/MenuConstants.java0000644000175000017500000000567612533641120030441 0ustar benbenpackage com.baselet.control.constants; import com.baselet.control.enums.Program; public class MenuConstants { // FILE public static final String FILE = "File"; public static final String NEW = "New"; public static final String OPEN = "Open..."; public static final String RECENT_FILES = "Recent files"; public static final String GENERATE_CLASS = "Generate Class Elements from Files or Directory..."; public static final String GENERATE_CLASS_OPTIONS = "Generate Class Element Options..."; public static final String SAVE = "Save"; public static final String SAVE_AS = "Save as..."; public static final String EXPORT_AS = "Export as..."; public static final String MAIL_TO = "Mail to..."; public static final String EDIT_CURRENT_PALETTE = "Edit Current Palette"; public static final String OPTIONS = "Options..."; public static final String PRINT = "Print..."; public static final String EXIT = "Exit"; // EDIT public static final String EDIT = "Edit"; public static final String UNDO = "Undo"; public static final String REDO = "Redo"; public static final String DELETE = "Delete"; public static final String SELECT_ALL = "Select All"; public static final String GROUP = "Group"; public static final String UNGROUP = "Ungroup"; public static final String CUT = "Cut"; public static final String COPY = "Copy"; public static final String PASTE = "Paste"; // CUSTOM ELEMENTS public static final String CUSTOM_ELEMENTS = "Custom Elements"; public static final String NEW_CE = "New..."; public static final String NEW_FROM_TEMPLATE = "New from Template"; public static final String EDIT_SELECTED = "Edit Selected..."; public static final String CUSTOM_ELEMENTS_TUTORIAL = "Custom Elements Tutorial..."; public static final String CUSTOM_ELEMENTS_TUTORIAL_URL = "http://www.umlet.com/ce/ce.htm"; // HELP public static final String HELP = "Help"; public static final String ONLINE_HELP = "Online Help..."; public static final String ONLINE_SAMPLE_DIAGRAMS = "Online Sample Diagrams..."; public static final String VIDEO_TUTORIAL = "Video Tutorial: Basic Use and Custom Elements..."; public static final String PROGRAM_HOMEPAGE = Program.getInstance().getProgramName() + " Homepage..."; public static final String RATE_PROGRAM = "Rate " + Program.getInstance().getProgramName() + " at Eclipse Marketplace..."; public static final String ABOUT_PROGRAM = "About " + Program.getInstance().getProgramName(); // CONTEXT ON ELEMENT public static final String SET_FOREGROUND_COLOR = "Set foreground color"; public static final String SET_BACKGROUND_COLOR = "Set background color"; public static final String ALIGN = "Align"; public static final String LAYER = "Layer"; public static final String LAYER_UP = "to front (layer +1)"; public static final String LAYER_DOWN = "to back (layer -1)"; // OTHERS public static final String SEARCH = "Search"; public static final String ZOOM = "Zoom to"; } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/constants/SharedConstants.java0000644000175000017500000000065212533641120030730 0ustar benbenpackage com.baselet.control.constants; /** * temporary separation of constants which are used by NewGridElement class (for an easier migration to a non-awt based gui) */ public class SharedConstants { public static final String UTF8_BOM = "\uFEFF"; public static final String LEFT_QUOTATION = "<<"; public static final String RIGHT_QUOTATION = ">>"; public static final int DEFAULT_GRID_SIZE = 10; } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/Matrix.java0000644000175000017500000000310412533641120025050 0ustar benbenpackage com.baselet.control; import java.util.ArrayList; import java.util.List; public class Matrix { private List> matrix = new ArrayList>(); /** * @return the row size */ public int rows() { return matrix.size(); } /** * @return the column size */ public int cols() { int longestCol = 0; for (List row : matrix) { if (row.size() > longestCol) { longestCol = row.size(); } } return longestCol; } public List row(int index) { return matrix.get(index); } public List col(int index) { List result = new ArrayList(cols()); for (List row : matrix) { if (index < row.size()) { result.add(row.get(index)); } else { result.add(null); } } return result; } public T cell(int row, int col) { return row(row).get(col); } public boolean hasMoreRowsThanCols() { return rows() > cols(); } public void invert() { List> result = new ArrayList>(cols()); for (int i = 0; i < cols(); i++) { result.add(col(i)); } matrix = result; } public void addLine(List line) { matrix.add(line); } public boolean isEmpty() { for (List row : matrix) { if (!row.isEmpty()) { return false; } } return true; } @Override public String toString() { StringBuilder sb = new StringBuilder(""); for (List row : matrix) { for (T value : row) { sb.append(value != null ? value : "null").append("\t"); } sb.append("\n"); } return sb.toString(); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/SharedUtils.java0000644000175000017500000001226312533641120026041 0ustar benbenpackage com.baselet.control; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; public class SharedUtils { private static final Logger log = Logger.getLogger(SharedUtils.class); public static int realignToGrid(double d) { return realignTo(true, d, false, SharedConstants.DEFAULT_GRID_SIZE); } /** * realigns a rectangle to the grid enlarging any side if necessary (eg: x=9, width=10, x2=19 will be realigned to x=0, width=20, x2=20) * * @param rectangle rectangle to realign * @return a realigned copy of the input rectangle * @param realignHeightAndWidth if true height and width are also realigned if necessary */ public static Rectangle realignToGrid(Rectangle rectangle, boolean realignHeightAndWidth) { int x = realignToGrid(false, rectangle.getX(), false); int y = realignToGrid(false, rectangle.getY(), false); if (realignHeightAndWidth) { int width = realignToGrid(false, rectangle.getX() - x + rectangle.getWidth(), true); // IMPORTANT: the difference from original x and realigned x must be added, otherwise the upper example would return x=0, width=10, x2=10. x2 would be too small int height = realignToGrid(false, rectangle.getY() - y + rectangle.getHeight(), true); return new Rectangle(x, y, width, height); } else { return new Rectangle(x, y, rectangle.getWidth(), rectangle.getHeight()); } } /** * rounds eg: 5 to 10, 4 to 0, -5 to -10, -4 to 0 */ public static int realignToGridRoundToNearest(boolean logRealign, double val) { boolean roundUp; if (Math.abs(val % SharedConstants.DEFAULT_GRID_SIZE) < SharedConstants.DEFAULT_GRID_SIZE / 2) { roundUp = val < 0; } else { roundUp = val >= 0; } return realignTo(logRealign, val, roundUp, SharedConstants.DEFAULT_GRID_SIZE); } public static int realignToGrid(boolean logRealign, double val, boolean roundUp) { return realignTo(logRealign, val, roundUp, SharedConstants.DEFAULT_GRID_SIZE); } /** * returns the integer which is nearest to val but on the grid (round down) * * @param logRealign * if true a realign is logged as an error * @param val * value which should be rounded to the grid * @param roundUp * if true the realign rounds up instead of down * @return value on the grid */ public static int realignTo(boolean logRealign, double val, boolean roundUp, int gridSize) { double alignedVal = val; double mod = val % gridSize; if (mod != 0) { alignedVal -= mod; // ExampleA: 14 - 4 = 10 // ExampleB: -14 - -4 = -10 // (positive vals get round down, negative vals get round up) if (val > 0 && roundUp) { // eg ExampleA: 10 + 10 = 20 (for positive vals roundUp must be specifically handled by adding gridSize) alignedVal += gridSize; } if (val < 0 && !roundUp) { // eg ExampleB: -10 - 10 = -20 (for negative vals roundDown must be specifically handled by subtracting gridSize) alignedVal -= gridSize; } if (logRealign) { log.error("realignToGrid from " + val + " to " + alignedVal); } } return (int) alignedVal; } public static String listToString(String sep, Collection list) { return listToStringHelper(new StringBuilder(), sep, list).toString(); } private static StringBuilder listToStringHelper(StringBuilder sb, String sep, Collection list) { for (Object line : list) { sb.append(line).append(sep); } if (sb.length() > 0) { sb.setLength(sb.length() - sep.length()); } return sb; } public static String mapToString(Map map) { return mapToString("\n", ",", map); } public static String mapToString(String mapSep, String listSep, Map map) { StringBuilder sb = new StringBuilder(); for (Entry e : map.entrySet()) { sb.append(e.getKey()).append(": "); if (e.getValue() instanceof Collection) { listToStringHelper(sb, listSep, (Collection) e.getValue()); } else { sb.append(e.getValue().toString()); } sb.append(mapSep); } if (sb.length() > 0) { sb.setLength(sb.length() - mapSep.length()); } return sb.toString(); } public static List mergeLists(List listA, List listB, List listC) { List returnList = new ArrayList(listA); returnList.addAll(listB); returnList.addAll(listC); return Collections.unmodifiableList(returnList); } public static Double[][] cloneArray(Double[][] src) { int length = src.length; Double[][] target = new Double[length][src[0].length]; for (int i = 0; i < length; i++) { System.arraycopy(src[i], 0, target[i], 0, src[i].length); } return target; } public static String[] cloneArray(String[] src) { String[] target = new String[src.length]; System.arraycopy(src, 0, target, 0, src.length); return target; } public static int[] cloneArray(int[] src) { int[] target = new int[src.length]; System.arraycopy(src, 0, target, 0, src.length); return target; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/StringStyle.java0000644000175000017500000000400712533641120026076 0ustar benbenpackage com.baselet.control; import java.util.HashSet; import java.util.Set; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.FormatLabels; public class StringStyle { public static final String ESCAPE_CHARACTER = "\\"; private static final String TEMP_REPLACEMENT = "§$§ä%§%ü/,"; private final Set format; private final String stringWithoutMarkup; public StringStyle(Set format, String stringWithoutMarkup) { super(); this.format = format; this.stringWithoutMarkup = stringWithoutMarkup; } public static String replaceNotEscaped(String line) { line = StringStyle.replaceNotEscaped(line, SharedConstants.LEFT_QUOTATION, "\u00AB"); line = StringStyle.replaceNotEscaped(line, SharedConstants.RIGHT_QUOTATION, "\u00BB"); return line; } /** * this method does not use "complex" regular expressions to avoid problems with compiling to GWT */ private static String replaceNotEscaped(String s, String old, String replacement) { s = s.replace(ESCAPE_CHARACTER + old, TEMP_REPLACEMENT); s = s.replace(old, replacement); s = s.replace(TEMP_REPLACEMENT, old); return s; } public static StringStyle analyzeFormatLabels(String s) { Set format = new HashSet(); if (s != null && !s.isEmpty()) { // As long as any text format applies the loop continues boolean matchFound = true; while (matchFound) { matchFound = false; for (FormatLabels formatLabel : FormatLabels.values()) { String markup = formatLabel.getValue(); if (s.startsWith(markup) && s.endsWith(markup) && s.length() > markup.length() * 2) { format.add(formatLabel); s = s.substring(markup.length(), s.length() - markup.length()); matchFound = true; } } } } return new StringStyle(format, s); } public Set getFormat() { return format; } public String getStringWithoutMarkup() { return stringWithoutMarkup; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/0000755000175000017500000000000012533641120024207 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/XValues.java0000644000175000017500000000343112533641120026442 0ustar benbenpackage com.baselet.control.basics; public class XValues { private Double left; private Double right; public XValues(double left, double right) { super(); this.left = left; this.right = right; } public double getLeft() { return left; } public double getRight() { return right; } public double getSpace() { return right - left; } public void addLeft(double inc) { left += inc; } public void subRight(double inc) { right -= inc; } public static XValues createForEllipse(double y, double height, double width) { double halfHeight = height / 2.0; double halfWidth = width / 2.0; double halfEllipseWidthOnY = Math.sqrt((1 - Math.pow(halfHeight - y, 2) / Math.pow(halfHeight, 2)) * Math.pow(halfWidth, 2)); XValues returnVal = new XValues(halfWidth - halfEllipseWidthOnY, halfWidth + halfEllipseWidthOnY); return returnVal; } /** * returns the intersection of both points [eg: (2,5) intersect (1,4) = (2,4)] * @param nanPriority if true then NaN has priority over other values, otherwise other values have priority */ public XValues intersect(XValues other, boolean nanPriority) { Double maxLeft = left; Double minRight = right; if (nanPriority) { if (other.left.equals(Double.NaN) || other.left > left) { maxLeft = other.left; } if (other.right.equals(Double.NaN) || other.right < right) { minRight = other.right; } } else { if (left.equals(Double.NaN) || other.left > left) { maxLeft = other.left; } if (right.equals(Double.NaN) || other.right < right) { minRight = other.right; } } return new XValues(maxLeft, minRight); } @Override public String toString() { return "XValues [left=" + left + ", right=" + right + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/0000755000175000017500000000000012533641120025136 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/Rectangle.java0000644000175000017500000001053612533641120027712 0ustar benbenpackage com.baselet.control.basics.geom; public class Rectangle { public int x; public int y; public int width; public int height; public Rectangle() { super(); } /** * TODO as with DimensionDouble and PointDouble, Rectangle should also contain only double values in future! */ public Rectangle(Double x, Double y, Double width, Double height) { this((int) Math.round(x), (int) Math.round(y), (int) Math.round(width), (int) Math.round(height)); } public Rectangle(int x, int y, int width, int height) { this(); setBounds(x, y, width, height); } public void setBounds(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public int getX() { return x; } public int getX2() { return x + width; } public void setX(int x) { this.x = x; } public int getY() { return y; } public int getY2() { return y + height; } public PointDouble getUpperLeftCorner() { return new PointDouble(x, y); } public PointDouble getCenter() { return new PointDouble(x + width / 2, y + height / 2); } public void setY(int y) { this.y = y; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public Dimension getSize() { return new Dimension(width, height); } public void setHeight(int height) { this.height = height; } public void move(int diffX, int diffY) { x += diffX; y += diffY; } public void addBorder(int border) { x -= border; y -= border; width += border * 2; height += border * 2; } public boolean contains(Point p) { return contains(new Rectangle(p.getX(), p.getY(), 0, 0)); } public boolean contains(Rectangle other) { return getX() <= other.getX() && getX2() >= other.getX2() && getY() <= other.getY() && getY2() >= other.getY2(); } public void setLocation(int x, int y) { this.x = x; this.y = y; } public void setSize(int width, int height) { this.width = width; this.height = height; } public boolean intersects(Rectangle other) { if (getY2() < other.getY()) { return false; } if (getY() > other.getY2()) { return false; } if (getX2() < other.getX()) { return false; } if (getX() > other.getX2()) { return false; } return true; } /** * move the bounds of this rectangle to the lowest upper/left and highest lower/right bounds * eg: Rect(x=-1,y=2,x2=3,y2=5).merge(Rect(x=2,y=1,x2=5,y2=3))=Rect(x=-1,y=1,x2=5,y2=5) */ public void merge(Rectangle other) { // must store X2 and Y2 before changing this X and Y, otherwise information can be lost // eg: this(y=100,h=10) and other(y=50,h=10) -> this.y2 is 110 but would be changed to 60) int oldX2 = getX2(); int oldY2 = getY2(); setX(Math.min(getX(), other.getX())); setY(Math.min(getY(), other.getY())); setWidth(Math.max(oldX2, other.getX2()) - getX()); setHeight(Math.max(oldY2, other.getY2()) - getY()); } public Rectangle copy() { return new Rectangle(x, y, width, height); } public Rectangle copyInverted() { return new Rectangle(-x, -y, -width, -height); } public Rectangle subtract(Rectangle other) { return new Rectangle(x - other.x, y - other.y, width - other.width, height - other.height); } public Rectangle add(Rectangle other) { return new Rectangle(x + other.x, y + other.y, width + other.width, height + other.height); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + height; result = prime * result + width; result = prime * result + x; result = prime * result + y; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Rectangle other = (Rectangle) obj; if (height != other.height) { return false; } if (width != other.width) { return false; } if (x != other.x) { return false; } if (y != other.y) { return false; } return true; } @Override public String toString() { return "Rectangle [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/Point.java0000644000175000017500000000255412533641120027100 0ustar benbenpackage com.baselet.control.basics.geom; public class Point { public int x; public int y; public Point() {} public Point(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public Point move(int diffX, int diffY) { x += diffX; y += diffY; return this; } public double distance(Point o) { double distX = o.getX() - getX(); double distY = o.getY() - getY(); return Math.sqrt(distX * distX + distY * distY); } public Point copy() { return new Point(x, y); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + x; result = prime * result + y; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Point other = (Point) obj; if (x != other.x) { return false; } if (y != other.y) { return false; } return true; } @Override public String toString() { return "p(x=" + x + ", y=" + y + ")"; } public PointDouble toPointDouble() { return new PointDouble(x, y); } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/DimensionDouble.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/DimensionDouble.jav0000644000175000017500000000073312533641120030723 0ustar benbenpackage com.baselet.control.basics.geom; public class DimensionDouble { private double height; private double width; public DimensionDouble(double width, double height) { super(); this.width = width; this.height = height; } public double getWidth() { return width; } public double getHeight() { return height; } @Override public String toString() { return "Dimension [height=" + height + ", width=" + width + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/PointDouble.java0000644000175000017500000000304312533641120030225 0ustar benbenpackage com.baselet.control.basics.geom; /** * an immutable point with double coordinates * must be immutable because equals and hashcode is overwritten and sets and maps can contain PointDouble as keys */ public class PointDouble { public final Double x; public final Double y; public PointDouble(double x, double y) { super(); this.x = x; this.y = y; } public Double getX() { return x; } public Double getY() { return y; } public double distance(PointDouble o) { double distX = o.getX() - getX(); double distY = o.getY() - getY(); return Math.sqrt(distX * distX + distY * distY); } public PointDouble copy() { return new PointDouble(x, y); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (x == null ? 0 : x.hashCode()); result = prime * result + (y == null ? 0 : y.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } PointDouble other = (PointDouble) obj; if (x == null) { if (other.x != null) { return false; } } else if (!x.equals(other.x)) { return false; } if (y == null) { if (other.y != null) { return false; } } else if (!y.equals(other.y)) { return false; } return true; } @Override public String toString() { return "p(x=" + x + " y=" + y + ")"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/Dimension.java0000644000175000017500000000233112533641120027725 0ustar benbenpackage com.baselet.control.basics.geom; /** * should be removed after every Dimension has been replaced by DimensionFloat */ public class Dimension { public int width; public int height; public Dimension() {} public Dimension(int width, int height) { super(); this.width = width; this.height = height; } public int getHeight() { return height; } public int getWidth() { return width; } public void setHeight(int height) { this.height = height; } public void setWidth(int width) { this.width = width; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + height; result = prime * result + width; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Dimension other = (Dimension) obj; if (height != other.height) { return false; } if (width != other.width) { return false; } return true; } @Override public String toString() { return "Dimension [width=" + width + ", height=" + height + "]"; } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/GeometricFunctions.javaumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/GeometricFunctions.0000644000175000017500000001022012533641120030741 0ustar benbenpackage com.baselet.control.basics.geom; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class GeometricFunctions { public static double distanceBetweenTwoPoints(PointDouble p1, PointDouble p2) { return GeometricFunctions.distanceBetweenTwoPoints(p1.x, p1.y, p2.x, p2.y); } public static double getDistanceBetweenLineAndPoint(PointDouble start, PointDouble end, PointDouble pointToCheck) { return getDistanceBetweenLineAndPoint(start.x, start.y, end.x, end.y, pointToCheck.x, pointToCheck.y); } private static double distanceBetweenTwoPoints(double x1, double y1, double x2, double y2) { double xDist = x1 - x2; double yDist = y1 - y2; return Math.sqrt(xDist * xDist + yDist * yDist); } /** * implementation is based on http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment/2233538#2233538 */ private static double getDistanceBetweenLineAndPoint(double x1, double y1, double x2, double y2, double checkX, double checkY) { double px = x2 - x1; double py = y2 - y1; double mult = px * px + py * py; double u = ((checkX - x1) * px + (checkY - y1) * py) / mult; if (u > 1) { u = 1; } else if (u < 0) { u = 0; } double x = x1 + u * px; double y = y1 + u * py; return GeometricFunctions.distanceBetweenTwoPoints(x, y, checkX, checkY); } /** * for math information see http://www.mathisfunforum.com/viewtopic.php?id=9657 */ public static PointDouble getPointOnLineWithDistanceFromStart(PointDouble start, PointDouble end, double distance) { double xDiff = end.getX() - start.getX(); double yDiff = end.getY() - start.getY(); double length = distanceBetweenTwoPoints(start, end); double distanceToGo = distance / length; return new PointDouble(start.getX() + xDiff * distanceToGo, start.getY() + yDiff * distanceToGo); } /** * from https://stackoverflow.com/questions/15594424/line-crosses-rectangle-how-to-find-the-cross-points/15594751#15594751 */ public static PointDouble getIntersectionPoint(Line lineA, Line lineB) { double x1 = lineA.getStart().getX(); double y1 = lineA.getStart().getY(); double x2 = lineA.getEnd().getX(); double y2 = lineA.getEnd().getY(); double x3 = lineB.getStart().getX(); double y3 = lineB.getStart().getY(); double x4 = lineB.getEnd().getX(); double y4 = lineB.getEnd().getY(); PointDouble p = null; double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (d != 0) { double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d; double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d; p = new PointDouble(xi, yi); // remove intersections which are not on the line (use 1 instead of 0 distance for tolerance) if (lineA.getDistanceToPoint(p) > 1 || lineB.getDistanceToPoint(p) > 1) { p = null; } } return p; } public static List getIntersectionPoints(Line line, Rectangle rectangle) { List list = Arrays.asList( // TOP getIntersectionPoint(line, new Line(new PointDouble(rectangle.getX(), rectangle.getY()), new PointDouble(rectangle.getX() + rectangle.getWidth(), rectangle.getY()))), // BOTTOM getIntersectionPoint(line, new Line(new PointDouble(rectangle.getX(), rectangle.getY() + rectangle.getHeight()), new PointDouble(rectangle.getX() + rectangle.getWidth(), rectangle.getY() + rectangle.getHeight()))), // LEFT getIntersectionPoint(line, new Line(new PointDouble(rectangle.getX(), rectangle.getY()), new PointDouble(rectangle.getX(), rectangle.getY() + rectangle.getHeight()))), // RIGHT getIntersectionPoint(line, new Line(new PointDouble(rectangle.getX() + rectangle.getWidth(), rectangle.getY()), new PointDouble(rectangle.getX() + rectangle.getWidth(), rectangle.getY() + rectangle.getHeight()))) ); // remove nulls List returnList = new ArrayList(); for (PointDouble p : list) { if (p != null) { returnList.add(p); } } return returnList; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/Lines.java0000644000175000017500000000070312533641120027053 0ustar benbenpackage com.baselet.control.basics.geom; import java.util.ArrayList; import java.util.List; public class Lines { public static List toPoints(Line... lines) { List points = new ArrayList(); for (Line line : lines) { for (PointDouble p : line.toPoints()) { if (points.isEmpty() || !points.get(points.size() - 1).equals(p)) { points.add(p); } } } return points; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/basics/geom/Line.java0000644000175000017500000000671112533641120026675 0ustar benbenpackage com.baselet.control.basics.geom; import java.util.List; import org.apache.log4j.Logger; import com.baselet.control.enums.Direction; public class Line { private static final Logger log = Logger.getLogger(Line.class); private final PointDouble start; private final PointDouble end; public Line(PointDouble start, PointDouble end) { super(); this.start = start; this.end = end; } public PointDouble getStart() { return start; } public PointDouble getEnd() { return end; } public PointDouble getPoint(boolean start) { return start ? getStart() : getEnd(); } public PointDouble getCenter() { return new PointDouble((start.getX() + end.getX()) / 2, (start.getY() + end.getY()) / 2); } public double getLength() { return GeometricFunctions.distanceBetweenTwoPoints(start, end); } public PointDouble getPointOnLineWithDistanceFrom(boolean fromStart, double distance) { if (fromStart) { return GeometricFunctions.getPointOnLineWithDistanceFromStart(start, end, distance); } else { // from end return GeometricFunctions.getPointOnLineWithDistanceFromStart(end, start, distance); } } public double getAngleOfSlope() { double radius = getLength(); double rad = Math.acos((start.x - end.x) / radius); double radDeg = Math.toDegrees(rad); if (start.y < end.y) { radDeg = 360 - radDeg; } return radDeg; } /** * Checks the distance between this line and a specific point * @param pointToCheck point to check the distance * @return minimal distance from point to line as double value */ public double getDistanceToPoint(PointDouble pointToCheck) { double dist = GeometricFunctions.getDistanceBetweenLineAndPoint(start, end, pointToCheck); log.trace("Minimal distance between " + this + " and " + pointToCheck + " is " + dist); return dist; } public PointDouble[] toPoints() { return new PointDouble[] { start, end }; } public Direction getDirectionOfLine(boolean directionOfStart) { double angleOfSlope = getAngleOfSlope(); Direction direction; if (angleOfSlope > 315 || angleOfSlope < 45) { direction = Direction.RIGHT; } else if (angleOfSlope < 135) { direction = Direction.DOWN; } else if (angleOfSlope < 225) { direction = Direction.LEFT; } else { direction = Direction.UP; } if (!directionOfStart) { direction = direction.invert(); } return direction; } public List getIntersectionPoints(Rectangle rectangle) { return GeometricFunctions.getIntersectionPoints(this, rectangle); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (end == null ? 0 : end.hashCode()); result = prime * result + (start == null ? 0 : start.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Line other = (Line) obj; if (end == null) { if (other.end != null) { return false; } } else if (!end.equals(other.end)) { return false; } if (start == null) { if (other.start != null) { return false; } } else if (!start.equals(other.start)) { return false; } return true; } @Override public String toString() { return "Line [start=" + start + ", end=" + end + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/ErrorMessages.java0000644000175000017500000000052012533641120026364 0ustar benbenpackage com.baselet.control; public class ErrorMessages { public static final String ERROR_SAVING_FILE = "An error occured during saving: "; public static final String ERROR_SAVING_EMPTY_DIAGRAM = "You cannot save or export an empty diagram."; public static final String ERROR_PRINTING = "An error occured during printing."; }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/config/0000755000175000017500000000000012533641120024210 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/config/SharedConfig.java0000644000175000017500000000166212533641120027414 0ustar benbenpackage com.baselet.control.config; public class SharedConfig { private static final SharedConfig instance = new SharedConfig(); public static SharedConfig getInstance() { return instance; } private boolean show_stickingpolygon = true; private boolean stickingEnabled = true; private boolean dev_mode = false; // TODO should be moved to a shared config class private SharedConfig() {} public boolean isShow_stickingpolygon() { return show_stickingpolygon; } public void setShow_stickingpolygon(boolean show_stickingpolygon) { this.show_stickingpolygon = show_stickingpolygon; } public boolean isStickingEnabled() { return stickingEnabled; } public void setStickingEnabled(boolean stickingEnabled) { this.stickingEnabled = stickingEnabled; } public boolean isDev_mode() { return dev_mode; } public void setDev_mode(boolean dev_mode) { this.dev_mode = dev_mode; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/0000755000175000017500000000000012533641120024072 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/AlignVertical.java0000644000175000017500000000013412533641120027457 0ustar benbenpackage com.baselet.control.enums; public enum AlignVertical { TOP, CENTER, BOTTOM } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/LineType.java0000644000175000017500000000065212533641120026471 0ustar benbenpackage com.baselet.control.enums; public enum LineType implements RegexValueHolder { SOLID("-"), DASHED("."), DOTTED(".."), DOUBLE("="), DOUBLE_DASHED(":"), DOUBLE_DOTTED("::"); private String value; private LineType(String value) { this.value = value; } public String getValue() { return value; } @Override public String getRegexValue() { return value.replaceAll("\\.", "\\\\."); } }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/Program.java0000644000175000017500000000261312533641120026346 0ustar benbenpackage com.baselet.control.enums; /** * PROGRAM, PLATTFORM AND JAVA SPECIFIC SETTINGS **/ public class Program { private static final Program instance = new Program(); public static Program getInstance() { return instance; } // Basically the RUNTIME_TYPE is STANDALONE until it gets overwritten after program startup private RuntimeType runtimeType = RuntimeType.STANDALONE; private String configName; private String programName; private String extension; private String website; private String version; public void init(String version) { programName = "UMLet"; extension = "uxf"; website = "http://www." + getProgramName().toLowerCase() + ".com"; if (Program.getInstance().getRuntimeType() == RuntimeType.STANDALONE) { configName = getProgramName().toLowerCase() + ".cfg"; } else { configName = getProgramName().toLowerCase() + "plugin.cfg"; } this.version = version; } public RuntimeType getRuntimeType() { return runtimeType; } public void setRuntimeType(RuntimeType runtimeType) { this.runtimeType = runtimeType; } public String getConfigName() { return configName; } public String getProgramName() { return programName; } public String getExtension() { return extension; } public String getWebsite() { return website; } public String getVersion() { return version; } }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/AlignHorizontal.java0000644000175000017500000000013612533641120030041 0ustar benbenpackage com.baselet.control.enums; public enum AlignHorizontal { LEFT, CENTER, RIGHT } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/RegexValueHolder.java0000644000175000017500000000015012533641120030136 0ustar benbenpackage com.baselet.control.enums; public interface RegexValueHolder { String getRegexValue(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/FormatLabels.java0000644000175000017500000000040712533641120027311 0ustar benbenpackage com.baselet.control.enums; public enum FormatLabels { UNDERLINE("_"), BOLD("*"), ITALIC("/"); private String value; private FormatLabels(String value) { this.value = value; } public String getValue() { return value; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/Direction.java0000644000175000017500000000066212533641120026661 0ustar benbenpackage com.baselet.control.enums; public enum Direction { LEFT, RIGHT, UP, DOWN; public boolean isHorizontal() { return this == LEFT || this == RIGHT; } public Direction invert() { switch (this) { case LEFT: return RIGHT; case RIGHT: return LEFT; case UP: return DOWN; case DOWN: return UP; default: throw new RuntimeException("missing invert mapping"); } } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/RuntimeType.java0000644000175000017500000000014612533641120027223 0ustar benbenpackage com.baselet.control.enums; public enum RuntimeType { STANDALONE, ECLIPSE_PLUGIN, BATCH }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/ElementStyle.java0000644000175000017500000000015412533641120027347 0ustar benbenpackage com.baselet.control.enums; public enum ElementStyle { AUTORESIZE, SIMPLE, NORESIZE, WORDWRAP }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/Priority.java0000644000175000017500000000045212533641120026557 0ustar benbenpackage com.baselet.control.enums; /** * priority enum, must be ordered from highest to lowest priority! * if a specific ordering is necessary but not possible with the current Priorities, just insert a new one in between */ public enum Priority { HIGHEST, HIGH, DEFAULT, LOW, LOWEST }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/control/enums/ElementId.java0000644000175000017500000000100412533641120026576 0ustar benbenpackage com.baselet.control.enums; /** * these IDs should NEVER be changed, because they are stored in uxf files * To add a new element, add an Id here, implement the getId() method of the element and the creation method in ElementFactory */ public enum ElementId { UMLClass, UMLUseCase, UMLInterface, UMLActor, UMLState, UMLObject, UMLTimer, UMLSpecialState, UMLNote, UMLSyncBarHorizontal, UMLSyncBarVertical, UMLPackage, UMLFrame, UMLDeployment, UMLGeneric, UMLHierarchy, Relation, Text, PlotGrid; }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/gui/0000755000175000017500000000000012533641120022047 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/gui/AutocompletionText.java0000644000175000017500000000153512533641120026565 0ustar benbenpackage com.baselet.gui; public class AutocompletionText { private String text; private final String info; private String base64Img; public AutocompletionText(String text, String info) { super(); this.text = text; this.info = info; } public AutocompletionText(String text, String info, String base64Img) { super(); this.text = text; this.info = info; this.base64Img = base64Img; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getInfo() { return info; } public String getHtmlInfo() { String baseText = getText() + " " + getInfo() + ""; if (base64Img != null) { baseText += " "; } return baseText; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/0000755000175000017500000000000012533641120022667 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/0000755000175000017500000000000012533641120023624 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/TextSplitter.java0000644000175000017500000000713112533641120027144 0ustar benbenpackage com.baselet.diagram.draw; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.ListIterator; import com.baselet.diagram.draw.helper.Style; public class TextSplitter { /** * Cache for already known results of splitstrings */ private static LinkedHashMap splitStringCache = new LinkedHashMap(100); public static boolean checkifStringFits(String text, double width, DrawHandler drawer) { return splitString(text, width, drawer).equals(text); } public static String splitString(String text, double width, DrawHandler drawer) { SplitStringCacheKey key = new SplitStringCacheKey(text, width, drawer.getStyleClone()); String result = splitStringCache.get(key); if (result != null) { return result; } result = splitStringAlgorithm(text, width, drawer); splitStringCache.put(key, result); return result; } private static String splitStringAlgorithm(String text, double width, DrawHandler drawer) { String splitChar = " "; width -= drawer.textWidth("n"); // subtract a buffer to make sure no character is hidden at the end ListIterator inputIter = new ArrayList(Arrays.asList(text.split(splitChar, -1))).listIterator(); // split limit is -1 to retain spaces at the end of the string StringBuilder sb = new StringBuilder(""); while (inputIter.hasNext()) { String nextEl = inputIter.next(); if (drawer.textWidth(sb.toString() + nextEl) > width) { inputIter.previous(); break; } sb.append(nextEl).append(splitChar); inputIter.remove(); } if (sb.length() > 0) { // cut the last splitChar sb.setLength(sb.length() - 1); } String line = sb.toString(); if (inputIter.hasNext() && line.isEmpty()) { // if the line has no space and would be to wide for one line String nextEl = inputIter.next(); String possibleLine = nextEl; while (!possibleLine.isEmpty() && drawer.textWidth(possibleLine) > width) { possibleLine = possibleLine.substring(0, possibleLine.length() - 1); } line = possibleLine; } return line; } private static class SplitStringCacheKey { private final String input; private final double width; private final Style style; // must be part of key, because text width also depends on styling like fontsize public SplitStringCacheKey(String input, double width, Style style) { super(); this.input = input; this.width = width; this.style = style; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (input == null ? 0 : input.hashCode()); result = prime * result + (style == null ? 0 : style.hashCode()); long temp; temp = Double.doubleToLongBits(width); result = prime * result + (int) (temp ^ temp >>> 32); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } SplitStringCacheKey other = (SplitStringCacheKey) obj; if (input == null) { if (other.input != null) { return false; } } else if (!input.equals(other.input)) { return false; } if (style == null) { if (other.style != null) { return false; } } else if (!style.equals(other.style)) { return false; } if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width)) { return false; } return true; } } }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/DrawHandler.java0000644000175000017500000001662712533641120026676 0ustar benbenpackage com.baselet.diagram.draw; import java.util.ArrayList; import java.util.Collection; import com.baselet.control.StringStyle; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.Lines; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.diagram.draw.helper.Style; import com.baselet.diagram.draw.helper.StyleException; public abstract class DrawHandler { protected static final double HALF_PX = 0.5f; protected Style style = new Style(); private final Style overlay = new Style(); private final ArrayList drawablesBackground = new ArrayList(); private final ArrayList drawablesForeground = new ArrayList(); public static enum Layer { Foreground, Background } private Layer layer = Layer.Background; private boolean enableDrawing = true; /** * all background elements are drawn before drawing the foreground elements * can be useful e.g. if a printText call is made before a drawRectangle call although it should be placed behind the rectangle */ public void setLayer(Layer layer) { this.layer = layer; } public void setEnableDrawing(boolean enableDrawing) { this.enableDrawing = enableDrawing; } protected Style getOverlay() { return overlay; } protected void addDrawable(DrawFunction drawable) { if (enableDrawing) { if (layer == Layer.Foreground) { drawablesForeground.add(drawable); } else { drawablesBackground.add(drawable); } } // if drawing is disabled don't add the DrawFunction to any collection } public void drawAll(boolean isSelected) { if (isSelected) { overlay.setForegroundColor(ColorOwn.SELECTION_FG); } else { overlay.setForegroundColor(null); } drawAll(); } public void clearCache() { drawablesBackground.clear(); drawablesForeground.clear(); } public final double textHeightMaxWithSpace() { return textHeightMax() + getDistanceBetweenTextLines(); } public final double textHeightMax() { return textDimension("Hy").getHeight(); // "Hy" is a good dummy for a generic max height and depth } public final double textHeight(String text) { return textDimension(text).getHeight(); } public final double textWidth(String text) { return textDimension(text).getWidth(); } public final void setForegroundColor(String color) { if (color.equals(FacetConstants.FOREGROUND_COLOR_KEY)) { setForegroundColor(ColorOwn.DEFAULT_FOREGROUND); } else { setForegroundColor(ColorOwn.forString(color, Transparency.FOREGROUND)); // if fgColor is not a valid string null will be set } } public final void setForegroundColor(ColorOwn color) { if (color == null) { style.setForegroundColor(ColorOwn.DEFAULT_FOREGROUND); } else { style.setForegroundColor(color); } } public final void setBackgroundColor(String color) { if (color.equals(FacetConstants.BACKGROUND_COLOR_KEY)) { setBackgroundColor(ColorOwn.DEFAULT_BACKGROUND); } else { setBackgroundColor(ColorOwn.forString(color, Transparency.BACKGROUND)); } } public final void setBackgroundColor(ColorOwn color) { if (color == null) { style.setBackgroundColor(ColorOwn.DEFAULT_BACKGROUND); } else { style.setBackgroundColor(color); } } public ColorOwn getForegroundColor() { return style.getForegroundColor(); } public ColorOwn getBackgroundColor() { return style.getBackgroundColor(); } public double getLineWidth() { return style.getLineWidth(); } public void resetColorSettings() { setForegroundColor(FacetConstants.FOREGROUND_COLOR_KEY); setBackgroundColor(FacetConstants.BACKGROUND_COLOR_KEY); } public final void setFontSize(double fontSize) { assertDoubleRange(fontSize); style.setFontSize(fontSize); } public double getFontSize() { return style.getFontSize(); } public final void setLineType(LineType type) { style.setLineType(type); } public LineType getLineType() { return style.getLineType(); } public final void setLineWidth(double lineWidth) { assertDoubleRange(lineWidth); style.setLineWidth(lineWidth); } private void assertDoubleRange(double doubleValue) { if (doubleValue <= 0 || doubleValue > 100) { throw new StyleException("value must be >0 and <=100"); } } public void resetStyle() { resetColorSettings(); style.setFontSize(getDefaultFontSize()); style.setLineType(LineType.SOLID); style.setLineWidth(1); } public Style getStyleClone() { return style.cloneFromMe(); } public void setStyle(Style style) { this.style = style.cloneFromMe(); } public void drawAll() { for (DrawFunction d : drawablesBackground) { d.run(); } for (DrawFunction d : drawablesForeground) { d.run(); } } public double getDistanceBorderToText() { return 5; } public double getDistanceBetweenTextLines() { return 3; } protected DimensionDouble textDimension(String string) { return textDimensionHelper(StringStyle.replaceNotEscaped(string)); } /* HELPER METHODS */ protected abstract DimensionDouble textDimensionHelper(String string); protected abstract double getDefaultFontSize(); /* DRAW METHODS */ public void drawRectangle(Rectangle rect) { drawRectangle(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); } public void drawLine(Line line) { drawLine(line.getStart().getX(), line.getStart().getY(), line.getEnd().getX(), line.getEnd().getY()); } public void drawLine(double x1, double y1, double x2, double y2) { drawLines(new PointDouble(x1, y1), new PointDouble(x2, y2)); } public void drawLines(Collection points) { drawLines(points.toArray(new PointDouble[points.size()])); } public void drawLines(Line... lines) { drawLines(Lines.toPoints(lines)); } public void print(String text, double x, double y, AlignHorizontal align) { print(text, new PointDouble(x, y), align); } protected String escape(String input) { return StringStyle.replaceNotEscaped(input); } public void print(String text, PointDouble point, AlignHorizontal align) { printHelper(StringStyle.replaceNotEscaped(text), point, align); } /** * @param x * @param y * @param width * @param height * @param start 0 starts as a horizontal line * @param extent can be up to 360 (extend in degrees from param start) */ public abstract void drawArc(double x, double y, double width, double height, double start, double extent, boolean open); public abstract void drawCircle(double x, double y, double radius); public abstract void drawEllipse(double x, double y, double width, double height); public abstract void drawLines(PointDouble... points); public abstract void drawRectangle(double x, double y, double width, double height); public abstract void drawRectangleRound(double x, double y, double width, double height, double radius); public abstract void printHelper(String text, PointDouble point, AlignHorizontal align); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/DrawFunction.java0000644000175000017500000000013612533641120027072 0ustar benbenpackage com.baselet.diagram.draw; public interface DrawFunction { public void run(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/helper/0000755000175000017500000000000012533641120025103 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/helper/Style.java0000644000175000017500000000637612533641120027062 0ustar benbenpackage com.baselet.diagram.draw.helper; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.LineType; public class Style { private LineType lineType; private double lineWidth; private ColorOwn foregroundColor; private ColorOwn backgroundColor; private double fontSize; private boolean applyZoom; public Style() { lineWidth = FacetConstants.LINE_WIDTH_DEFAULT; lineType = LineType.SOLID; applyZoom = true; } public Style cloneFromMe() { Style clone = new Style(); clone.lineWidth = lineWidth; clone.lineType = lineType; clone.foregroundColor = foregroundColor; clone.backgroundColor = backgroundColor; clone.fontSize = fontSize; clone.applyZoom = applyZoom; return clone; } public void setLineType(LineType lineType) { this.lineType = lineType; } public LineType getLineType() { return lineType; } public void setLineWidth(double lineWidth) { this.lineWidth = lineWidth; } public double getLineWidth() { return lineWidth; } public void setForegroundColor(ColorOwn foregroundColor) { this.foregroundColor = foregroundColor; } public ColorOwn getForegroundColor() { return foregroundColor; } public void setBackgroundColor(ColorOwn backgroundColor) { this.backgroundColor = backgroundColor; } public ColorOwn getBackgroundColor() { return backgroundColor; } public void setFontSize(double fontSize) { this.fontSize = fontSize; } public double getFontSize() { return fontSize; } public void setApplyZoom(boolean applyZoom) { this.applyZoom = applyZoom; } public boolean isApplyZoom() { return applyZoom; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (applyZoom ? 1231 : 1237); result = prime * result + (backgroundColor == null ? 0 : backgroundColor.hashCode()); result = prime * result + (foregroundColor == null ? 0 : foregroundColor.hashCode()); long temp; temp = Double.doubleToLongBits(fontSize); result = prime * result + (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(lineWidth); result = prime * result + (int) (temp ^ temp >>> 32); result = prime * result + (lineType == null ? 0 : lineType.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Style other = (Style) obj; if (applyZoom != other.applyZoom) { return false; } if (backgroundColor == null) { if (other.backgroundColor != null) { return false; } } else if (!backgroundColor.equals(other.backgroundColor)) { return false; } if (foregroundColor == null) { if (other.foregroundColor != null) { return false; } } else if (!foregroundColor.equals(other.foregroundColor)) { return false; } if (Double.doubleToLongBits(fontSize) != Double.doubleToLongBits(other.fontSize)) { return false; } if (Double.doubleToLongBits(lineWidth) != Double.doubleToLongBits(other.lineWidth)) { return false; } if (lineType != other.lineType) { return false; } return true; } }umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/helper/StyleException.java0000644000175000017500000000047412533641120030732 0ustar benbenpackage com.baselet.diagram.draw.helper; public class StyleException extends RuntimeException { private static final long serialVersionUID = 1L; public StyleException(String message) { super(message); } public StyleException(String message, Throwable cause) { super(message, cause); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/diagram/draw/helper/ColorOwn.java0000644000175000017500000001516112533641120027514 0ustar benbenpackage com.baselet.diagram.draw.helper; import java.util.HashMap; public class ColorOwn { public static final String EXAMPLE_TEXT = "color string (green,...) or code (#3c7a00,...)"; public static enum Transparency { FOREGROUND(255), FULL_TRANSPARENT(0), BACKGROUND(125), SELECTION_BACKGROUND(20); private int alpha; private Transparency(int alpha) { this.alpha = alpha; } public int getAlpha() { return alpha; } } public static final ColorOwn RED = new ColorOwn(255, 0, 0, Transparency.FOREGROUND); public static final ColorOwn GREEN = new ColorOwn(0, 255, 0, Transparency.FOREGROUND); public static final ColorOwn BLUE = new ColorOwn(0, 0, 255, Transparency.FOREGROUND); public static final ColorOwn YELLOW = new ColorOwn(255, 255, 0, Transparency.FOREGROUND); public static final ColorOwn MAGENTA = new ColorOwn(255, 0, 255, Transparency.FOREGROUND); public static final ColorOwn WHITE = new ColorOwn(255, 255, 255, Transparency.FOREGROUND); public static final ColorOwn BLACK = new ColorOwn(0, 0, 0, Transparency.FOREGROUND); public static final ColorOwn ORANGE = new ColorOwn(255, 165, 0, Transparency.FOREGROUND); public static final ColorOwn CYAN = new ColorOwn(0, 255, 255, Transparency.FOREGROUND); public static final ColorOwn DARK_GRAY = new ColorOwn(70, 70, 70, Transparency.FOREGROUND); public static final ColorOwn GRAY = new ColorOwn(120, 120, 120, Transparency.FOREGROUND); public static final ColorOwn LIGHT_GRAY = new ColorOwn(200, 200, 200, Transparency.FOREGROUND); public static final ColorOwn PINK = new ColorOwn(255, 175, 175, Transparency.FOREGROUND); public static final ColorOwn TRANSPARENT = WHITE.transparency(Transparency.FULL_TRANSPARENT); // color white is important because EPS export doesn't support transparency, therefore background will be white public static final ColorOwn SELECTION_FG = BLUE; public static final ColorOwn SELECTION_BG = new ColorOwn(0, 0, 255, Transparency.SELECTION_BACKGROUND); public static final ColorOwn STICKING_POLYGON = new ColorOwn(100, 180, 255, Transparency.FOREGROUND); public static final ColorOwn SYNTAX_HIGHLIGHTING = new ColorOwn(0, 100, 255, Transparency.FOREGROUND); public static final ColorOwn DEFAULT_FOREGROUND = BLACK; public static final ColorOwn DEFAULT_BACKGROUND = TRANSPARENT; public static final HashMap COLOR_MAP = new HashMap(); static { COLOR_MAP.put("black", ColorOwn.BLACK); COLOR_MAP.put("blue", ColorOwn.BLUE); COLOR_MAP.put("cyan", ColorOwn.CYAN); COLOR_MAP.put("dark_gray", ColorOwn.DARK_GRAY); COLOR_MAP.put("gray", ColorOwn.GRAY); COLOR_MAP.put("green", ColorOwn.GREEN); COLOR_MAP.put("light_gray", ColorOwn.LIGHT_GRAY); COLOR_MAP.put("magenta", ColorOwn.MAGENTA); COLOR_MAP.put("orange", ColorOwn.ORANGE); COLOR_MAP.put("pink", ColorOwn.PINK); COLOR_MAP.put("red", ColorOwn.RED); COLOR_MAP.put("white", ColorOwn.WHITE); COLOR_MAP.put("yellow", ColorOwn.YELLOW); } /* fields should be final to avoid changing parts of existing color object (otherwise unexpected visible changes can happen) */ private final int red; private final int green; private final int blue; private final int alpha; public ColorOwn(int red, int green, int blue, Transparency transparency) { this(red, green, blue, transparency.getAlpha()); } public ColorOwn(int red, int green, int blue, int alpha) { this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } public ColorOwn(String hex) { int i = Integer.decode(hex); red = i >> 16 & 0xFF; green = i >> 8 & 0xFF; blue = i & 0xFF; alpha = Transparency.FOREGROUND.getAlpha(); } public int getRed() { return red; } public int getGreen() { return green; } public int getBlue() { return blue; } public int getAlpha() { return alpha; } public ColorOwn transparency(Transparency transparency) { return transparency(transparency.getAlpha()); } public ColorOwn transparency(int alpha) { return new ColorOwn(getRed(), getGreen(), getBlue(), alpha); } public ColorOwn darken(int factor) { return new ColorOwn(Math.max(0, getRed() - factor), Math.max(0, getGreen() - factor), Math.max(0, getBlue() - factor), getAlpha()); } /** * Converts colorString into a Color which is available in the colorMap or if not tries to decode the colorString * * @param colorString * String which describes the color * @return Color which is related to the String or null if it is no valid colorString */ public static ColorOwn forStringOrNull(String colorString, Transparency transparency) { try { return forString(colorString, transparency); } catch (StyleException e) { return null; } } /** * Converts colorString into a Color which is available in the colorMap or if not tries to decode the colorString * * @param colorString * String which describes the color * @return Color which is related to the String or null if it is no valid colorString */ public static ColorOwn forString(String colorString, Transparency transparency) { boolean error = false; ColorOwn returnColor = null; if (colorString == null) { error = true; } else { for (String color : COLOR_MAP.keySet()) { if (colorString.equalsIgnoreCase(color)) { returnColor = COLOR_MAP.get(color); break; } } if (returnColor == null) { try { returnColor = new ColorOwn(colorString); } catch (NumberFormatException e) { error = true; } } if (returnColor != null) { returnColor = returnColor.transparency(transparency); } } if (error) { throw new StyleException("value must be a " + EXAMPLE_TEXT); } return returnColor; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + alpha; result = prime * result + blue; result = prime * result + green; result = prime * result + red; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ColorOwn other = (ColorOwn) obj; if (alpha != other.alpha) { return false; } if (blue != other.blue) { return false; } if (green != other.green) { return false; } if (red != other.red) { return false; } return true; } @Override public String toString() { return "ColorOwn [red=" + red + ", green=" + green + ", blue=" + blue + ", alpha=" + alpha + "]"; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/0000755000175000017500000000000012533641120022701 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/RemoveGridElementCommand.java0000644000175000017500000000105212533641120030416 0ustar benbenpackage com.baselet.command; import java.util.List; import com.baselet.element.interfaces.GridElement; public class RemoveGridElementCommand extends Command { private CommandTarget target; private List elements; public RemoveGridElementCommand(CommandTarget target, List elements) { this.target = target; this.elements = elements; } @Override public void execute() { target.removeGridElements(elements); } @Override public void undo() { target.addGridElements(elements); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/Controller.java0000644000175000017500000000271612533641120025675 0ustar benbenpackage com.baselet.command; import java.util.ArrayList; import java.util.List; import java.util.Vector; public class Controller { private List commands = new ArrayList(); private int _cursor; public Controller() { _cursor = -1; } protected void executeCommand(Command newCommand) { // Remove future commands for (int i = commands.size() - 1; i > _cursor; i--) { commands.remove(i); } commands.add(newCommand); newCommand.execute(); if (commands.size() >= 2) { Command c_n, c_nMinus1; c_n = commands.get(commands.size() - 1); c_nMinus1 = commands.get(commands.size() - 2); if (c_n.isMergeableTo(c_nMinus1)) { commands.remove(c_n); commands.remove(c_nMinus1); Command c = c_n.mergeTo(c_nMinus1); commands.add(c); } } _cursor = commands.size() - 1; } public void undo() { if (isUndoable()) { Command c = commands.get(_cursor); c.undo(); _cursor--; } } public void redo() { if (isRedoable()) { Command c = commands.get(_cursor + 1); c.execute(); _cursor++; } } public boolean isEmpty() { return commands.isEmpty(); } public boolean isUndoable() { return _cursor >= 0; } public boolean isRedoable() { return _cursor < commands.size() - 1; } public long getCommandCount() { return commands.size(); } public void clear() { commands = new Vector(); _cursor = -1; } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/AddGridElementCommand.java0000644000175000017500000000104412533641120027652 0ustar benbenpackage com.baselet.command; import java.util.List; import com.baselet.element.interfaces.GridElement; public class AddGridElementCommand extends Command { private CommandTarget target; private List elements; public AddGridElementCommand(CommandTarget target, List elements) { this.target = target; this.elements = elements; } @Override public void execute() { target.addGridElements(elements); } @Override public void undo() { target.removeGridElements(elements); } } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/CommandTarget.java0000644000175000017500000000102612533641120026270 0ustar benbenpackage com.baselet.command; import java.util.List; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.Selector; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; public interface CommandTarget { void addGridElements(List element); void removeGridElements(List element); Selector getSelector(); Diagram getDiagram(); Rectangle getVisibleBounds(); void updatePropertiesPanelWithSelectedElement(); } umlet-2015-06-03_UMLet_v13.3/BaseletElements/src/com/baselet/command/Command.java0000644000175000017500000000055112533641120025123 0ustar benbenpackage com.baselet.command; public abstract class Command { public abstract void execute(); public abstract void undo(); public boolean isMergeableTo(@SuppressWarnings("unused") Command c) { return false; } public Command mergeTo(@SuppressWarnings("unused") Command c) { return null; } public boolean isChangingDiagram() { return true; } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/0000755000175000017500000000000012533641120015164 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/.project0000644000175000017500000000163312533641120016636 0ustar benben BaseletGWT org.eclipse.wst.common.project.facet.core.builder org.eclipse.jdt.core.javabuilder com.google.gdt.eclipse.core.webAppProjectValidator com.google.gwt.eclipse.core.gwtProjectValidator org.eclipse.jdt.core.javanature com.google.gwt.eclipse.core.gwtNature org.eclipse.wst.common.project.facet.core.nature umlet-2015-06-03_UMLet_v13.3/BaseletGWT/build.xml0000644000175000017500000000663412533641120017016 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.classpath0000644000175000017500000000135112533641120017147 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.gitignore0000644000175000017500000000006712533641120017157 0ustar benben/war/WEB-INF/classes/ /war/baseletgwt/ /gwt-unitCache/ umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/0000755000175000017500000000000012533641120017102 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/com.google.gdt.eclipse.core.prefs0000644000175000017500000000020212533641120025315 0ustar benbeneclipse.preferences.version=1 jarsExcludedFromWebInfLib= launchConfigExternalUrlPrefix= warSrcDir=war warSrcDirIsOutput=true umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/org.eclipse.wst.common.project.facet.core.xml0000644000175000017500000000017212533641120027616 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/org.eclipse.jdt.core.prefs0000644000175000017500000005720512533641120024075 0ustar benbeneclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.7 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true org.eclipse.jdt.core.formatter.comment.format_block_comments=true org.eclipse.jdt.core.formatter.comment.format_header=true org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false org.eclipse.jdt.core.formatter.comment.format_line_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert org.eclipse.jdt.core.formatter.comment.line_length=9999 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=false org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=false org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=999 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false org.eclipse.jdt.core.formatter.tabulation.char=tab org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/org.eclipse.jdt.ui.prefs0000644000175000017500000001217212533641120023554 0ustar benbencleanup.add_default_serial_version_id=false cleanup.add_generated_serial_version_id=true cleanup.add_missing_annotations=true cleanup.add_missing_deprecated_annotations=true cleanup.add_missing_methods=false cleanup.add_missing_nls_tags=false cleanup.add_missing_override_annotations=true cleanup.add_missing_override_annotations_interface_methods=true cleanup.add_serial_version_id=false cleanup.always_use_blocks=true cleanup.always_use_parentheses_in_expressions=false cleanup.always_use_this_for_non_static_field_access=false cleanup.always_use_this_for_non_static_method_access=false cleanup.convert_to_enhanced_for_loop=true cleanup.correct_indentation=false cleanup.format_source_code=true cleanup.format_source_code_changes_only=false cleanup.make_local_variable_final=true cleanup.make_parameters_final=false cleanup.make_private_fields_final=false cleanup.make_type_abstract_if_missing_method=false cleanup.make_variable_declarations_final=false cleanup.never_use_blocks=false cleanup.never_use_parentheses_in_expressions=true cleanup.organize_imports=true cleanup.qualify_static_field_accesses_with_declaring_class=false cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true cleanup.qualify_static_member_accesses_with_declaring_class=true cleanup.qualify_static_method_accesses_with_declaring_class=false cleanup.remove_private_constructors=true cleanup.remove_trailing_whitespaces=true cleanup.remove_trailing_whitespaces_all=true cleanup.remove_trailing_whitespaces_ignore_empty=false cleanup.remove_unnecessary_casts=true cleanup.remove_unnecessary_nls_tags=true cleanup.remove_unused_imports=false cleanup.remove_unused_local_variables=false cleanup.remove_unused_private_fields=true cleanup.remove_unused_private_members=false cleanup.remove_unused_private_methods=true cleanup.remove_unused_private_types=true cleanup.sort_members=false cleanup.sort_members_all=false cleanup.use_blocks=true cleanup.use_blocks_only_for_return_and_throw=false cleanup.use_parentheses_in_expressions=true cleanup.use_this_for_non_static_field_access=true cleanup.use_this_for_non_static_field_access_only_if_necessary=true cleanup.use_this_for_non_static_method_access=true cleanup.use_this_for_non_static_method_access_only_if_necessary=true cleanup_profile=_Umlet Cleanup cleanup_settings_version=2 eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_Umlet Formatter formatter_settings_version=12 sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true sp_cleanup.add_missing_deprecated_annotations=true sp_cleanup.add_missing_methods=false sp_cleanup.add_missing_nls_tags=false sp_cleanup.add_missing_override_annotations=true sp_cleanup.add_missing_override_annotations_interface_methods=true sp_cleanup.add_serial_version_id=false sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false sp_cleanup.convert_to_enhanced_for_loop=true sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false sp_cleanup.make_variable_declarations_final=true sp_cleanup.never_use_blocks=false sp_cleanup.never_use_parentheses_in_expressions=true sp_cleanup.on_save_use_additional_actions=true sp_cleanup.organize_imports=true sp_cleanup.qualify_static_field_accesses_with_declaring_class=false sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_with_declaring_class=true sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true sp_cleanup.remove_trailing_whitespaces=true sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true sp_cleanup.remove_unnecessary_nls_tags=true sp_cleanup.remove_unused_imports=false sp_cleanup.remove_unused_local_variables=false sp_cleanup.remove_unused_private_fields=true sp_cleanup.remove_unused_private_members=false sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false sp_cleanup.use_blocks=true sp_cleanup.use_blocks_only_for_return_and_throw=false sp_cleanup.use_parentheses_in_expressions=true sp_cleanup.use_this_for_non_static_field_access=true sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=true sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/com.google.gwt.eclipse.core.prefs0000644000175000017500000000070512533641120025350 0ustar benbeneclipse.preferences.version=1 entryPointModules= filesCopiedToWebInfLib=gwt-servlet.jar gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBW11dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14NTEybV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5iYXNlbGV0Lmd3dC5CYXNlbGV0R1dUPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= umlet-2015-06-03_UMLet_v13.3/BaseletGWT/.settings/org.eclipse.core.resources.prefs0000644000175000017500000000007112533641120025313 0ustar benbeneclipse.preferences.version=1 encoding/=UTF-8 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/0000755000175000017500000000000012533641120015755 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/index.html0000644000175000017500000000715012533641120017755 0ustar benben UMLetino - Free Online UML Tool for Fast UML Diagrams



UMLetino is a free online UML tool for fast UML diagrams. It runs in your browser, and does not require any installs.
It is based on UMLet (which is available as stand-alone tool or Eclipse plugin), and shares its fast, text-based way of drawing UML sketches.
Main features: install-free web app; save diagrams in browser storage; support for many UML diagram types; simple, markup-based UML element modifications; png export.

New in current version 13.3: new command transparency= to set transparency, several bugfixes

Start UMLetino NOW! (JavaScript and Cookies required)




umlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/UMLetino_logo_small.png0000644000175000017500000001570012533641120022372 0ustar benben‰PNG  IHDR¾šIò½sRGB®ÎégAMA± üa pHYsÃÃÇo¨dUIDATx^í]ytÕyçbÀ6›Ù7›Õì e)¥¥ ‡h‰'„$%mB!4 !$ÊVÞdÙ–lÙò ÊÞ”ôÐ@ %ià’–²eË’-K¶$k³ÛX_¿;sŸæÍ»OïÉ~oæÎ¼ûó;Oš¹sç»ßýÝï~w™™½Ä‰“ G|')ŽøN*RñK,‹ü÷ È“½"wŠ|£MäêV‘‹›EÎY/rv“ÈÉëD¦­9àï8Æã<ÿ'-"×m¹}³È¼.‘úE~7,Ò¿Ë¿“’ˆ#þHÓ‘Ç{Dþ®Ý#ö± ñ¾«E&¯98´Qäà(àœãùã€ãCà1‚ç™îH¤?˜„|&!Ïý€Ñ`.EÃøÅOа6íôq2nqć¬Ñmùìœ$# Nr“°$ñ4ó„2€=ó?`£`ƒ`#ã¹ëУ<ŠØÞÆIqâˆ_@¶Ü NÒ‘hS@8’ÿ‡É5ØÈ¨!àèw.Â¥û;¼ÞÈI~qÄ7ÈûÛEnÙ¡&‚Lôè6½Ø+0\bˆÅF:㆙g¸ž Wñ²´dH†I {>°7à¸`ï/<{mÀ/¨G|ʃ öÙ.Ðc–+N ,ÏÑh$Š2®D¯t©Xâ÷ìò¦ 9@åìÉÔ{÷ñ€½Æ ß–Tp¨8â÷"Þýê&ÏÃ3†Wó邤z†ˆ €6X¼Õ7NIEN—7ÇÎø½ †njÍàšD¥HEÿu êNô=\¥„4㞥S¸°YdmL…¦šøk®ÜàMIªA«#ý˜ }¸FA{}w‹oÄ”Jj‰_‡¸•q<wáÇÚëxN‡¦u 4uÄ.÷½¼ kö $>Wƒojól›&Iñ5è \ SE:ŒÚûŸÕ$Ò•¢àÔÿnĤ\q¥—2U Ãž ` ¼Òï<ᒠ⟷^ä@TŠ‹åË Îüйܙ‚o¢‰¿]/+ƒ«¦Šr(=è\èd.jö+!¡’Xâ7l÷^¸ÞTAåÇQ§áWÍ&$PIü7\go8u¤Oôƒø¶‹ÕÄoÇ€i2Hïfo’®«œ¿Þ¯DKÅjâÓ€8™Œë`7¸¿çê~EZ(ÖŸop›Í’ >Øò=K·7XIüÙÞLÆtH8ÇñÙ›îé·Žø|s™›¶L8Ðå[,vX¶µÁ*âíòbCËdĤ‚8 –‘ƒv‚3VYç y$«ýi‹_É–ˆUÄ¿ ÙÛÿa2^R ÉËA9+œ ™ûØïò—`Ç4§6‰œpæJŸÓéè%i 6 §é~IËÅÖ±†ø|F–Æ1-  ç`œ¤Ý§AäLúæ6o›Å›ßZvˆì,ÐÝ£ÇãºÅlYØ%ò5\OïÏÐ ClI]Ï`Ãe¼ÿÛ!¿°1‹ÄïC…“ôI«TêK²sŸ ½û­í"?/Ã@Ž æ¹>‘¯ø/Âbãâ;÷“Ö è×3Ú Vÿ/6zÄ1ËFлsGâDà[ {Ô^ìUô×´z”oBKŠÃ`CeÏ5Ç‚'vâÿ;*‘^, Þ‹ñ6Ÿ>bȱ܂÷Nö,rÇfL$¡PGêË^>N‰øìþlß’ÀÊÒoa[aé‹V‚%¡zÙîDØ»=Vœ+ñùÐ2g=l¾#èÝ9ëR“€«òI(¾—o€¶y«íÊ^þm úã’Øˆ¿ Ý4=”­Ý3õâK©¸u"iï“ù`Ø{V9Kíˆɩܸ$6âóÝôüZ‡É(qƒÓ‘ôüdg’…ßî¢÷·qA ’3yOöùÊF,±Ÿ]²­Ó—z–¤9%o æ  8 ·1ôÑ«ÖqH,ħ·'ÁLƈ ô@$§VÓ&|k4çý9^±i<¥½þ¿Æðv¶È‰Ïý8¶½ÐUWÀ×SørÔŒŒˆœ½Þÿ ŒÁq=W¹£–ȉo›·'é¹wæ6èU rI³7¶²…üÔƒŽïJŠR"'>[$›ÉQC{ú´!,Âó«ù~ƒMâ'þ(âWFJ|~f’Ký¦ÂG ’žº\¿ÉW®Â„Ój¿OÈ.qoÑX½ÝW.‰”ø'¡€¶¬Ò2ÜúŒe{ģߖÙö@Üä•DFüß ùaŽ¡ÐQƒ]kœ‹'¶ÈxXÖ‰  Ôc­¨$2âsoº ;0i`¦’ö®ÇrÉc=öläJþ -hEF|>µÉÊåVâTÐ÷\‹Žsl˜icèÕ+I"!>¿3ËÙSa£{œ)\ *…Ð6qomPŽ)¢p'âß`A˜ÃÞÆ†}à¶ WOmy¸zΧÍÊ-‘ŸƒÉ¸½ §.éðrbö†ÜÖ`²_Tàý¿ÁsىϹYΘ âÜ •$iÅ€?îF:H’¿ÜRvâÏßê½*ÃTȨpîÿlJ>SYn¹aé‘1÷Îû£wþ Ì»cÄ/Ï«®®l9šjŠSqïSðë¤8iÇè@:ª£Ä¡hxUe~â-Cü÷6ï’½î½.!¾ïã @=L::dæú*eÛ¯6Ž>J—!þû[@üû`0ÛÁ!e·_[g"~ˆ? Ê^sRpûuG|‡Šƒ#¾CE¿Â1k(¦tiCɉo2äXyÌoz œ^£®c]kJ¯aJ_è^Q‚º˜`JÊñÒâVùçÅ›ä)à`ym›W>Sú4¡¤Ä‡Áž\´I~¸¨M÷ñ< {ÈÜmæ|@ú[vªktzVÂŒê­yÒʧæõÊ¿ NOü×Ï©é›8~zÕ6TnkεKkÛóW6Ž?ºß Ècb¾2E èpbUŸœ»œëã¢y=8^DÝÍY±Fdy£‡Ò¿¬I7¦OJKü!‰•«eêÜ~s> ÕOëZCÆ_#3k6#½ˆ8v5—~‘gÖ=ˆ•rø\¦ ]£ÝÞ_Ò–«*{Dzuù+{&Ê´2·LSò•)j@ï_Ômðl²«ä 9E4LÖ—*ÓZ`úÝ\¿>¿-Ò„’?Ë*â¸|ÞÑ÷¦Þ5:}£<¸p Ò›‰Õün•&“>ƒFxb4“çÆ½O®ôHÔMa­tUÙŠø¹e:ؽ_DÖoÒœ"=þÊÏ.ϲµùm‘&¤‡ø¸çеrÉë³gYÜŽ4æëb'>ó1Á”6Œ=!>γ w˜ ð—(úÞah½ƒ0¥+S>¦ô»ƒôŸh”ZäÇú™køk o1Ÿ×Ôåš„c yDä9WçütÁk5xþ‘˜æ_c™2ÀÿÆ¦ÊÆ1Ô[¡û Æ(ÙåZ+ÍK×K3εõMRUkQæ­8·ÁO· øÍ’u<+û_VÝ­¿LKôàÚ¯.è„¶Ë ·ÊÀ²fO÷o¬UåºÇU~…lÅóh8Ôl•MK1fQv†Ý•=ø»N:ê[dQmÒ—€üÉ'>ï¥áÝof *C“ÆôˆÆèõ‘Ÿ×à^/c<¢*5c¯l<àÖuµ,Oˆ<øÿ­% ˆ²EðÚpÒ<¶È0MÉúR:è´ª!mÛÏàÄB0=ò}N¥­~c(ŸÀý1nxnq¨å:¡jéé‚ù„ò"ÔùurѼþ±ó,„4ÿ­º6õ; T¯Gþ5 6ïó+ÎìõÃß‘Ÿé¡Ó»KPæ¬ Fþ,©ãÁûá俞0«¢¡ïÛðΣùèòh0HÃiÛ¢äÔ׳:FÛ‡î“É+¨§ÿÔ|3n8va€8Cï†CèÇ…¯QRÿ1@ýL÷Ãqñ÷Kñ‡äCNí†_uxê–@ž·-Șè©ßhÖ·JKü!yMÍ© åú깸=c¤½835<ÿ?#ßül!㫼‡0àêBcë;€{¸]9s®tÄÿ‰ÅkXAù,þ>BžÁ¼¼ß}0èΤ××è¿Õña„Ir¸iG(txiñÆ@žž~§ÀdòÐ^ç_+ñqÝ}5]Jß`Úòe¦Ï'êá÷KXÎìû×£ÇT6 æ[ JJ|¤½:3 Vn£´ eÞ€{(*ïl„>‹kY`ž TþîG‘CšLþEŸ×ñï,èëKD|”§Mn¨Îƒzœ?·*šð÷øp ½s@•on½²¿Þ¢z€a9 eˆ1Â- «䤹}£ùiÀVÏfF^äNUN "¯CæÊS…{y×é²EMüA™€ß ~~Èy_þÎRëÙºòÿ£`£œrƒRŸ…kYÊî+L~*ŠcY÷ÓÀXœ×Í{ÏbŸÈ·4Ä'xl ĺ±{˜*3®Rz: ,k’5à˜N÷~§å!>G¸LžëÔ>æÃ§«rúoÐN6ÿï {6&"œW£¬Ê·W'nâ3=Ž?®V«‹´Òý ½œÊ/lbQrâªð~KVž ÆR…¢Ñ|ècøå’ýùùv!<¯åF)tûÞµqMžY 0÷ŸU£ò²® =µ*ðtS±À=nšoØ&@@}@Ö§s×( ä_“Ç>´!g«òXg Ê5*Ĥ­õ5|`#>Òi$>Îeî[ìÊg‹bm¯êÄ_õQVº÷–æÙõ©¯n_G(¬Â:]ö,{øy-_¯¶0ì鉲Ÿð C£\÷PM·,ªíP3/‡÷©‚w¿cAb4¦ó Qè^8?iÎ69g^¯œ^Õ§p6âè¼Ïô†4û‚<ÁëÏNò^ã|ÎW§/gãš1êàqeŸa¹x^Ÿ²OmÀ> 0˜½Ìç„U¬[Ð)CòÅù=jcóÐùp6É8 …ÿi?­3m10ÞÇŠ²=ÿ‚6;˜–oJ[ÿŽ\8i¿~ÔaàÊ2,Á/÷8ý±Ú‘Y„-ŠAÙˆ¯¡ ¤ …ƒÐÇM×åC0¿ LiM0]K˜Òj˜Ò S~AÓæ³aº6ŒBùŒuM¦t„)-±»éLÐiÃe(TŽñ¢ìÄwp°Žø G|‡Š„#¾CE"ñÛâßû?€ü÷–X6h“nf˜l5J]gàö¿­6ÿã‘鑞¡Òaûö9µaDŽùhD¦Æ„#~?"7¶Œˆì0ëè0Š^€všŽ:;Ö`˨p8ê쯛¡ øcÒswÐ98"ïýÜU†øå’¿i9rù[GQ`0¹Q¤¿<ŸøJü|г—É–Qáàµ"O•ùc}e'þ³}ÞçüM_·‹ ‡£"¿Ñæ+ädL9o½÷]b“£?5ºïj‘îѨ¤,RvâÃÓN@Aâüv*ï= :l-³1“.?éõì4Í`èp,êêÓh|å–²Ÿr. ™ øÑà+7ø 91 m÷èƒ÷FðúHˆ?»SäPƆ‚Fzý‰ðf/º=å®-"SbI‰ýQGÿ;ä+UF‰„øüT|ÜáÕçâ“&ï‚h$œ õÃÈ ‰„ø”Ó1Z;Ü!Ø•^Ûê+åDÉѨ—ã,©›ï¡ç‰B"#þÂ.;ºR5Ð…u[}Å*\® áL¶ŠPs6çýa_±2KdÄçÚÁ'âïN ê@#ÿO±¤ÍR g÷,Ž£éøJ"#>åª"GYà]víS Kß._¹ “ú¼Æoƒ#"æÃVݾrH¤ÄcÀ›Y±ÁÃ\¨á`7°’]ò‰O¢¦ZBz6>ê¥DJ|Ê)(¨ ƒ\‚ ;Î&TŠ|Ò3¼‰{¾>ˆ8VÖ#'þËý"“Ñ­ÙÒÅ’ü ¿NÂïÇ)÷ü¿ô¦•m"½òöûõF¼ª9ñ)4¼ ÓgÊóƒüœuÚ°ÃW2eò ŽMá½ý1죊…øOöŠH¯o0Dœ`Æ1È›‹¤IìÙÏBÒÓÛS¯;}E#”XˆO¡‡µ©ËÕ N¬Œ»#ZH)·üù»BË Ž¾ÓbblÄ_Ñ-r€¥BØ#qs][ Þ¨ò_èµØˆJØÖ³´1{×–˜BËØˆO9Í’m ùÀ6€9]¾Â  _¿ÉÛ{cÓ8* zûk¡g\+ñ9èÏë[\AŒ‹ù g}^³<ö_†^”ž[l·édÔ{gŒ½i¬Ä§p¯[¿É@6A|?ƒ˜™a„M²„§~ìl7¡ÃHn—ˆSb'>1c¬oÛŒƒ ¬4†? #ÎB˜ötŸ_ˆd!ͬNoå™=’í„×àjù°]Ü;ñ) Yy6wÏAp°¨=ì!ÀMmÑM>ƒÆvåFoŸ ÷%…ðë—Nãÿ"Ú9–XA|Š&“É`6ƒ=C5N²!Ì)ëz”ªrßò<û%ÍÞª+Wš“â$4X¿l¨·´û‹Y¬!þG ŠM»wl$%{Ðà…Dœe¹¯CäQ4†Gܬ÷‹øÿs8ίßܹYäsh<'"¿½q=ÛdˆdÛp†‰o[ÄâS£â9€4.‰ QYáŒÃ9ÓÂAÍ1M<Î-$ÍS‘ãí@§öö _шUħ\±Á«|“’ ö~s®Ù$ÖŸBâ§ÉãU2X—W t³M¬$þ;è¹U5É1­ƒç¼¶Ù(VŸRÕåm3ÔÁ~ÐiqоØ(֟§r8Eh2¬ƒ½Ð¤ÿA_‘ŠÕħ|ƒÝ¸ßÂæP<8_ÏEª‡,̆ÅzâS8Î)A“¡ìIÏu‡[-Y¤KA| WuùðŠÉàñƒ¤ç+B®KÈ[êCüî]Þ"7‰™ ïÓs;ŸöJŠ$†ø”~_¯„ÒØ*Á!Z(ÒÃÓ_ØìWRB$QħŒŒx¯šãˆ›ç´?·[pc^Ò$qÄ×ÂOÖ°{uä´;×YnÝìWHÂ$±Ä§\†˜’óü.ì‰܅ʧÜMšTI4ñ)7·{‹%Ix‚+ à‹¤!á_–I<ñ)ü²"MâüZ_%€ã*>t“†×«§‚ø”öÞ iUܪ0‡={S:–«4]YHRC|-|ÚÉÆ×å%ìEIz›÷ÝìŽ¤Žø”¡’øð»e7ë³{ Ý¸{*þŽëmgå”TŸ2°Käó=ïÏ™ Š Ï=ôôòw$tª²I-ñµðan¾‚ƒÏ»ºð'?èè øÌó%-"M)}]º–Ô_ ß~ìÂ3èè¸êÅ_’¥T ñ)ëáÅøÊBz5µß§Â ÏAú´¼½X©(âkYË€øŸql%ö$<îáÞùo¶‹t$ôUè{"I|-Œc¿„€ï|Iû¦7–M‡4Üæq<ü`…~ê”RÑÄ×Ò ÷·m^ày&ò$´2vç.Jžñ;qÄϾcžïÂg#`ü›¤—²jì|bûäùÂK7ˆ¼”ð½5¥Gü<Ò°Ý H ®ØþþJ†1ôì eøN"~Æh!¼{_ÄŸÑLŠ8â! {¯2¿ Ùûd&CŽ âlšèl“ §j/‡g¯CÕåÈ^PñÇ)ü ÃO6|½Á¢!pfˆÓ£°1Œ#˜&ÂŽ Y˜{®¦’ält솑è£A¾5à+ç¤hqÄ/¼á‰^‘ooö¸æëP19N 'ÖoCfãàîQ‚ÄeC!™õ±àÛ”Ù˜xýQ ý§¶pûÅ?vˆ¼ˆFלòUÕ(Ä¿ŒÂƒâ?á‘ù%“ÇzDf#îžpÁèïÑPfÃcs¦…Çù T¾'ŸïËçu•<ÝXnqÄwR‘âˆï¤"ÅßIEŠ#¾“ ‘ÿF·.‹cûCþIEND®B`‚umlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/umletino.html0000644000175000017500000000214112533641120020475 0ustar benben UMLetino - Free Online UML Tool for Fast UML Diagrams
umlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/WEB-INF/0000755000175000017500000000000012537353206017015 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/WEB-INF/web.xml0000644000175000017500000000066612533641120020313 0ustar benben index.html umlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/favicon.ico0000644000175000017500000000217612533641120020104 0ustar benben h(  @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgÿÿÿgÿÿÿgÿÿýgÿÿÿgÿüïgÿô¶gÿí‡gÿì„gÿó²gÿüígÿÿÿgÿÿügÿÿÿgÿÿÿgÿÿÿgÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿùÝÿÿíÿÿæYÿÿãCÿÿãBÿÿåVÿÿíˆÿÿùØÿÿÿýÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿùØÿÿãBÿÿÞ!ÿÿÝÿÿÝÿÿÝÿÿÝÿÿÞ!ÿÿâ<ÿÿ÷Ïÿÿÿþÿÿÿþÿÿÿÿÿÿþþÿÿþüÿÿø×ÿÿâ>ÿÿÝÿÿÞ#ÿÿá=ÿÿèiÿÿèkÿÿâ@ÿÿÞ$ÿÿÞÿÿá7ÿÿ÷Ïÿÿþýÿÿþþÿÿþüÿÿýôÿÿîÿÿß!ÿÿà&ÿÿémÿÿ÷Óÿÿýûÿÿýûÿÿø×ÿÿêtÿÿà'ÿÿß ÿÿìwÿÿýñÿÿþüÿûÖ¬ÿúËÿúÁ:ÿû¼ÿû½ÿúÊÿúÍ¢ÿûÍ›ÿúÍŸÿúÍÿúË…ÿû¾%ÿû¼ÿûÀ3ÿûʇÿûÕ¬ÿ÷7ÿîŠPÿí`ÿîŒOÿíŒ]ÿí^ÿîŒSÿìŽnÿìŽjÿîŒVÿîŒTÿíŒWÿí^ÿìŽoÿï‰Lÿ÷œ4ÿ÷œ5ÿîˆKÿî‹Vÿëpÿè‘ÿìhÿòˆ+ÿðŠ?ÿîŒVÿìŒ`ÿïŠMÿïŠLÿï‹Lÿð‹Cÿñ‡1ÿ÷›3ÿûË–ÿù½uÿùµ0ÿù±ÿù²ÿù½nÿùÁÿúÀxÿúÀyÿùÁÿù¾qÿú²ÿú°ÿú´"ÿú¼hÿûË•ÿÿþþÿÿýòÿÿëwÿÿÞ ÿÿß&ÿÿëzÿÿûâÿÿþýÿÿþýÿÿûæÿÿì‚ÿÿß(ÿÿÞ!ÿÿêoÿÿüïÿÿþýÿÿÿþÿÿþýÿÿ÷Íÿÿà4ÿÿÞ ÿÿÞ%ÿÿäKÿÿëÿÿìÿÿäOÿÿÞ&ÿÿÞ!ÿÿà.ÿÿöÄÿÿþüÿÿþþÿÿÿÿÿÿÿþÿÿÿþÿÿöÈÿÿá4ÿÿÞ ÿÿÝÿÿÜÿÿÜÿÿÝÿÿÞ ÿÿà0ÿÿõ¿ÿÿÿýÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿýÿÿ÷Ïÿÿë|ÿÿäJÿÿá6ÿÿá6ÿÿãGÿÿêwÿÿöÈÿÿÿýÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿgÿÿÿgÿÿÿgÿÿügÿÿÿgÿûägÿï–gÿèdgÿçbgÿî’gÿúßgÿþþgÿÿügÿÿÿgÿÿÿgÿÿÿgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿumlet-2015-06-03_UMLet_v13.3/BaseletGWT/war/umletino.css0000644000175000017500000000163112533641120020324 0ustar benben .gwt-PopupPanel { background-color: white; padding: 0px !important; } .centerPopup { border: 2px solid black !important; } .centerPopupContent { padding: 2px !important; } .exportPopup { font-size: 130%; font-weight: bold; text-align: center; } .menuPopup { border: 2px solid #E3E8F3 !important; padding: 0px !important; } .popupHeader { text-transform: uppercase; font-weight: bold; font-size: 0.8em; letter-spacing: 1px; color: white; background-color: black; padding-bottom: 0.1em; } .mainView { outline:none; } * { /* Prevent any object from being highlighted upon touch event*/ -webkit-tap-highlight-color: rgba(0,0,0,0); } .gwt-SuggestBoxPopup { /* overflow: auto !important; */ /* max-height: 400px; */ background-color: white !important; } .gwt-SuggestBoxPopup .item { font-size: 90% !important; padding: 0px !important; }umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/0000755000175000017500000000000012533641120015753 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/0000755000175000017500000000000012533641120016531 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/BaseletElements.gwt.xml0000644000175000017500000000062612533641120023133 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/0000755000175000017500000000000012533641120020150 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/0000755000175000017500000000000012533641120020751 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/BaseletGWT.gwt.xml0000644000175000017500000000474612533641120024247 0ustar benben umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/0000755000175000017500000000000012533641120022227 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/0000755000175000017500000000000012533641120023660 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/ComponentGwt.java0000644000175000017500000000422412533641120027151 0ustar benbenpackage com.baselet.gwt.client.element; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.draw.DrawHandler; import com.baselet.element.interfaces.Component; import com.baselet.element.interfaces.GridElement; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.dom.client.CanvasElement; public class ComponentGwt implements Component { boolean redrawNecessary = true; private Canvas canvas = Canvas.createIfSupported(); private DrawHandlerGwt drawer = new DrawHandlerGwt(canvas); private DrawHandlerGwt metadrawer = new DrawHandlerGwt(canvas); private GridElement element; private Rectangle rect; public ComponentGwt(GridElement element) { this.element = element; } @Override public void setBoundsRect(Rectangle rect) { this.rect = rect; } @Override public Rectangle getBoundsRect() { return rect.copy(); } @Override public void repaintComponent() { // repainting is currently not controlled by the gridelement itself } @Override public void afterModelUpdate() { redrawNecessary = true; } @Override public DrawHandler getDrawHandler() { return drawer; } @Override public DrawHandler getMetaDrawHandler() { return metadrawer; } private boolean lastSelected = false; public void drawOn(Context2d context, boolean isSelected) { if (redrawNecessary || lastSelected != isSelected) { redrawNecessary = false; CanvasElement el = canvas.getCanvasElement(); canvas.getContext2d().clearRect(0, 0, el.getWidth(), el.getHeight()); canvas.getCanvasElement().setWidth(rect.getWidth() + 1); // canvas size is +1px to make sure a rectangle with width pixels is still visible (in Swing the bound-checking happens in BaseDrawHandlerSwing because you cannot extend the clipping area) canvas.getCanvasElement().setHeight(rect.getHeight() + 1); drawer.drawAll(isSelected); if (isSelected) { metadrawer.drawAll(); } } lastSelected = isSelected; context.drawImage(canvas.getCanvasElement(), element.getRectangle().getX(), element.getRectangle().getY()); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/DrawHandlerGwt.java0000644000175000017500000002722512533641120027410 0ustar benbenpackage com.baselet.gwt.client.element; import org.apache.log4j.Logger; import com.baselet.control.StringStyle; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.FormatLabels; import com.baselet.control.enums.LineType; import com.baselet.diagram.draw.DrawFunction; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.Style; import com.baselet.gwt.client.base.Converter; import com.baselet.gwt.client.base.Notification; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.canvas.dom.client.Context2d.TextAlign; public class DrawHandlerGwt extends DrawHandler { private static final Logger log = Logger.getLogger(DrawHandlerGwt.class); private final Canvas canvas; private final Context2d ctx; public DrawHandlerGwt(Canvas canvas) { this.canvas = canvas; ctx = canvas.getContext2d(); } @Override protected DimensionDouble textDimensionHelper(String string) { StringStyle stringStyle = StringStyle.analyzeFormatLabels(string); ctxSetFont(style.getFontSize(), stringStyle); DimensionDouble dim = new DimensionDouble(ctx.measureText(stringStyle.getStringWithoutMarkup()).getWidth(), style.getFontSize()); // unfortunately a html canvas offers no method to get the exakt height, therefore just use the fontsize return dim; } @Override protected double getDefaultFontSize() { return 12; } @Override public void drawArc(final double x, final double y, final double width, final double height, final double start, final double extent, final boolean open) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); double centerX = (int) (x + width / 2) + HALF_PX; double centerY = (int) (y + height / 2) + HALF_PX; ctx.save(); // translate the arc and don't use the center parameters because they are affected by scaling ctx.translate(centerX, centerY); ctx.scale(1, height / width); if (open) { // if arc should be open, move before the path begins ctx.beginPath(); } else { // otherwise the move is part of the path ctx.beginPath(); ctx.moveTo(0, 0); } ctx.arc(0, 0, width / 2, -Math.toRadians(start), -Math.toRadians(start + extent), true); if (!open) { // close path only if arc is not open ctx.closePath(); } // restore before drawing so the line has the same with and is not affected by the scaling ctx.restore(); ctx.fill(); ctx.stroke(); } }); } @Override public void drawCircle(final double x, final double y, final double radius) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); ctx.beginPath(); ctx.arc((int) x + HALF_PX, (int) y + HALF_PX, radius, 0, 2 * Math.PI); ctx.fill(); ctx.stroke(); } }); } @Override public void drawEllipse(final double x, final double y, final double width, final double height) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); drawEllipseHelper(ctx, (int) x + HALF_PX, (int) y + HALF_PX, width, height); } }); } @Override public void drawLines(final PointDouble... points) { if (points.length > 1) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); drawLineHelper(points); } }); } } @Override public void drawRectangle(final double x, final double y, final double width, final double height) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); // int cast on x/y + HALF_PX and int cast on width/height is important to make sure it never draws between pixels ctx.fillRect((int) x + HALF_PX, (int) y + HALF_PX, (int) width, (int) height); ctx.beginPath(); ctx.rect((int) x + HALF_PX, (int) y + HALF_PX, (int) width, (int) height); ctx.stroke(); } }); } @Override public void drawRectangleRound(final double x, final double y, final double width, final double height, final double radius) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { setStyle(ctx, styleAtDrawingCall); drawRoundRectHelper(ctx, (int) x + HALF_PX, (int) y + HALF_PX, (int) width, (int) height, radius); } }); } @Override public void printHelper(final String text, final PointDouble point, final AlignHorizontal align) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { PointDouble pToDraw = point; ColorOwn fgColor = getOverlay().getForegroundColor() != null ? getOverlay().getForegroundColor() : styleAtDrawingCall.getForegroundColor(); ctx.setFillStyle(Converter.convert(fgColor)); for (String line : text.split("\n")) { drawTextHelper(line, pToDraw, align, styleAtDrawingCall.getFontSize()); pToDraw = new PointDouble(pToDraw.getX(), pToDraw.getY() + textHeightMax()); } } }); } private void drawTextHelper(final String text, PointDouble p, AlignHorizontal align, double fontSize) { StringStyle stringStyle = StringStyle.analyzeFormatLabels(text); ctxSetFont(fontSize, stringStyle); String textToDraw = stringStyle.getStringWithoutMarkup(); if (textToDraw == null || textToDraw.isEmpty()) { return; // if nothing should be drawn return (some browsers like Opera have problems with ctx.fillText calls on empty strings) } if (stringStyle.getFormat().contains(FormatLabels.UNDERLINE)) { ctx.setLineWidth(1.0f); setLineDash(ctx, LineType.SOLID, 1.0f); double textWidth = textWidth(textToDraw); int vDist = 1; switch (align) { case LEFT: drawLineHelper(new PointDouble(p.x, p.y + vDist), new PointDouble(p.x + textWidth, p.y + vDist)); break; case CENTER: drawLineHelper(new PointDouble(p.x - textWidth / 2, p.y + vDist), new PointDouble(p.x + textWidth / 2, p.y + vDist)); break; case RIGHT: drawLineHelper(new PointDouble(p.x - textWidth, p.y + vDist), new PointDouble(p.x, p.y + vDist)); break; } } ctxSetTextAlign(align); ctx.fillText(textToDraw, p.x, p.y); } private void ctxSetFont(double fontSize, StringStyle stringStyle) { String htmlStyle = ""; if (stringStyle.getFormat().contains(FormatLabels.BOLD)) { htmlStyle += " bold"; } if (stringStyle.getFormat().contains(FormatLabels.ITALIC)) { htmlStyle += " italic"; } ctx.setFont(htmlStyle + " " + fontSize + "px sans-serif"); } private void ctxSetTextAlign(AlignHorizontal align) { TextAlign ctxAlign = null; switch (align) { case LEFT: ctxAlign = TextAlign.LEFT; break; case CENTER: ctxAlign = TextAlign.CENTER; break; case RIGHT: ctxAlign = TextAlign.RIGHT; break; } ctx.setTextAlign(ctxAlign); } /** * based on http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas/2173084#2173084 */ private static void drawEllipseHelper(Context2d ctx, double x, double y, double w, double h) { double kappa = .5522848f; double ox = w / 2 * kappa; // control point offset horizontal double oy = h / 2 * kappa; // control point offset vertical double xe = x + w; // x-end double ye = y + h; // y-end double xm = x + w / 2; // x-middle double ym = y + h / 2; // y-middle ctx.beginPath(); ctx.moveTo(x, ym); ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); ctx.fill(); ctx.stroke(); } /** * based on http://js-bits.blogspot.co.at/2010/07/canvas-rounded-corner-rectangles.html */ private static void drawRoundRectHelper(Context2d ctx, final double x, final double y, final double width, final double height, final double radius) { ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.lineTo(x + width - radius, y); ctx.quadraticCurveTo(x + width, y, x + width, y + radius); ctx.lineTo(x + width, y + height - radius); ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); ctx.lineTo(x + radius, y + height); ctx.quadraticCurveTo(x, y + height, x, y + height - radius); ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); ctx.fill(); ctx.stroke(); } private void drawLineHelper(PointDouble... points) { ctx.beginPath(); boolean first = true; for (PointDouble point : points) { if (first) { ctx.moveTo(point.x.intValue() + HALF_PX, point.y.intValue() + HALF_PX); // +0.5 because a line of thickness 1.0 spans 50% left and 50% right (therefore it would not be on the 1 pixel - see https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Applying_styles_and_colors) first = false; } ctx.lineTo(point.x.intValue() + HALF_PX, point.y.intValue() + HALF_PX); } if (points[0].equals(points[points.length - 1])) { ctx.fill(); // only fill if first point == lastpoint } ctx.stroke(); } private void setStyle(Context2d ctx, Style style) { if (style.getBackgroundColor() != null) { ctx.setFillStyle(Converter.convert(style.getBackgroundColor())); } ColorOwn fgColor = getOverlay().getForegroundColor() != null ? getOverlay().getForegroundColor() : style.getForegroundColor(); if (fgColor != null) { ctx.setStrokeStyle(Converter.convert(fgColor)); } ctx.setLineWidth(style.getLineWidth()); setLineDash(ctx, style.getLineType(), style.getLineWidth()); } private void setLineDash(Context2d ctx, LineType lineType, double lineThickness) { try { switch (lineType) { case DASHED: // large linethickness values need longer dashes setLineDash(ctx, 6 * Math.max(1, lineThickness / 2)); break; case DOTTED: // minimum must be 2, otherwise the dotting is not really visible setLineDash(ctx, Math.max(2, lineThickness)); break; default: // default is a solid line setLineDash(ctx, 0); } } catch (Exception e) { log.debug("No browser support for dashed lines", e); Notification.showFeatureNotSupported("Dashed and dotted lines are shown as solid lines
To correctly display them, please use Firefox or Chrome", true); } } /** * Chrome and Firefox 33+ support setLineDash() * Older Firefox version support only mozDash() */ public final native void setLineDash(Context2d ctx, double dash) /*-{ if (ctx.setLineDash !== undefined) { if (dash != 0) { ctx.setLineDash([ dash ]); } else { ctx.setLineDash([]); // Firefox 33+ on Linux dont show solid lines if ctx.setLineDash([0]) is used, therefore use empty array which works on every browser } } else if (ctx.mozDash !== undefined) { if (dash != 0) { ctx.mozDash = [ dash ]; } else { // default is null ctx.mozDash = null; } } else if (dash != 0) { // if another line than a solid one should be set and the browser doesn't support it throw an Exception throw new Exception(); } }-*/; } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/DiagramXmlParser.java0000644000175000017500000001651112533641120027731 0ustar benbenpackage com.baselet.gwt.client.element; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.ElementId; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.gwt.client.base.Notification; import com.baselet.gwt.client.version.BuildProperties; import com.google.gwt.http.client.URL; import com.google.gwt.user.client.Window; import com.google.gwt.xml.client.DOMException; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.Element; import com.google.gwt.xml.client.Node; import com.google.gwt.xml.client.NodeList; import com.google.gwt.xml.client.XMLParser; public class DiagramXmlParser { private static final String NUMBER_SIGN = "#"; // # is not automatically encoded by URL.encode() and URL.decode() private static final String NUMBER_SIGN_URL_ENCODED = "%23"; private static final String GT = ">"; private static final String GT_ENCODED = ">"; // in some cases the xml parser doesn't convert automatically (especially together with URL.encoded strings) therefore replace manually private static final String LT = "<"; private static final String LT_ENCODED = "<"; private static final String AMP = "&"; private static final String AMP_ENCODED = "&"; private static final Logger log = Logger.getLogger(DiagramXmlParser.class); private static final String DIAGRAM = "diagram"; private static final String ELEMENT = "element"; private static final String ZOOM_LEVEL = "zoom_level"; private static final String HELP_TEXT = "help_text"; private static final String ID = "id"; private static final String COORDINATES = "coordinates"; private static final String X = "x"; private static final String Y = "y"; private static final String W = "w"; private static final String H = "h"; private static final String PANEL_ATTRIBUTES = "panel_attributes"; private static final String ADDITIONAL_ATTRIBUTES = "additional_attributes"; private static final String ATTR_PROGRAM = "program"; private static final String ATTR_VERSION = "version"; public static Diagram xmlToDiagram(boolean decodeUrl, String xml) { if (decodeUrl) { xml = URL.decode(xml).replace(NUMBER_SIGN_URL_ENCODED, NUMBER_SIGN); } return xmlToDiagram(xml); } public static Diagram xmlToDiagram(String xml) { if (xml.startsWith(SharedConstants.UTF8_BOM)) { xml = xml.substring(1); // remove BOM if it is given } Diagram diagram = null; String helpText = null; try { // parse the XML document into a DOM Document messageDom = XMLParser.parse(xml); Node helpTextNode = messageDom.getElementsByTagName(HELP_TEXT).item(0); if (helpTextNode != null) { helpText = helpTextNode.getFirstChild().getNodeValue(); } float zoomScale = 1.0f; Node zoomElement = messageDom.getElementsByTagName(ZOOM_LEVEL).item(0); if (zoomElement != null) { zoomScale = Float.valueOf(zoomElement.getFirstChild().getNodeValue()) / SharedConstants.DEFAULT_GRID_SIZE; } diagram = new DiagramGwt(helpText, new ArrayList()); NodeList elements = messageDom.getElementsByTagName(ELEMENT); for (int i = 0; i < elements.getLength(); i++) { Element element = (Element) elements.item(i); try { ElementId id = ElementId.valueOf(element.getElementsByTagName(ID).item(0).getFirstChild().getNodeValue()); Element coord = (Element) element.getElementsByTagName(COORDINATES).item(0); Rectangle rect = new Rectangle(getInt(coord, X), getInt(coord, Y), getInt(coord, W), getInt(coord, H)); String panelAttributes = ""; Node panelAttrNode = element.getElementsByTagName(PANEL_ATTRIBUTES).item(0).getFirstChild(); if (panelAttrNode != null) { panelAttributes = panelAttrNode.getNodeValue().replace(LT_ENCODED, LT).replace(GT_ENCODED, GT).replace(AMP_ENCODED, AMP); } String additionalPanelAttributes = ""; Node additionalAttrNode = element.getElementsByTagName(ADDITIONAL_ATTRIBUTES).item(0); if (additionalAttrNode != null && additionalAttrNode.getFirstChild() != null) { additionalPanelAttributes = additionalAttrNode.getFirstChild().getNodeValue(); } if (zoomScale != 1.0f) { rect.setX((int) (rect.getX() / zoomScale)); rect.setY((int) (rect.getY() / zoomScale)); rect.setWidth((int) (rect.getWidth() / zoomScale)); rect.setHeight((int) (rect.getHeight() / zoomScale)); } GridElement gridElement = ElementFactoryGwt.create(id, rect, panelAttributes, additionalPanelAttributes, diagram); diagram.getGridElements().add(gridElement); } catch (Exception e) { log.error("Element has invalid XML structure: " + element, e); Notification.showFeatureNotSupported("Diagram has invalid element: " + element, true); } } } catch (DOMException e) { log.error("Parsing error", e); Window.alert("Could not parse XML document."); } return diagram; } private static Integer getInt(Element coordinates, String tag) { return Integer.valueOf(coordinates.getElementsByTagName(tag).item(0).getFirstChild().getNodeValue()); } public static String diagramToXml(Diagram diagram) { Document doc = XMLParser.createDocument(); Element diagramElement = doc.createElement(DIAGRAM); diagramElement.setAttribute(ATTR_PROGRAM, "umlet_web"); diagramElement.setAttribute(ATTR_VERSION, BuildProperties.getVersion()); diagramElement.appendChild(create(doc, ZOOM_LEVEL, doc.createTextNode("10"))); String helpText = diagram.getPanelAttributes(); if (helpText != null) { diagramElement.appendChild(create(doc, HELP_TEXT, doc.createTextNode(helpText))); } doc.appendChild(diagramElement); for (GridElement ge : diagram.getGridElements()) { diagramElement.appendChild( create(doc, ELEMENT, create(doc, ID, doc.createTextNode(ge.getId().toString())), create(doc, COORDINATES, create(doc, X, doc.createTextNode(ge.getRectangle().getX() + "")), create(doc, Y, doc.createTextNode(ge.getRectangle().getY() + "")), create(doc, W, doc.createTextNode(ge.getRectangle().getWidth() + "")), create(doc, H, doc.createTextNode(ge.getRectangle().getHeight() + ""))), create(doc, PANEL_ATTRIBUTES, doc.createTextNode(ge.getPanelAttributes().replace(LT, LT_ENCODED).replace(GT, GT_ENCODED).replace(AMP, AMP_ENCODED))), create(doc, ADDITIONAL_ATTRIBUTES, doc.createTextNode(ge.getAdditionalAttributes())) )); } return doc.toString(); } public static String diagramToXml(boolean encodeUrl, Diagram diagram) { String xml = diagramToXml(diagram); if (encodeUrl) { xml = URL.encode(xml).replace(NUMBER_SIGN, NUMBER_SIGN_URL_ENCODED); } return xml; } private static Element create(Document doc, String name, Node... children) { Element element = doc.createElement(name); for (Node c : children) { element.appendChild(c); } return element; } public static String gridElementsToXml(List gridElements) { return diagramToXml(new DiagramGwt(gridElements)); } public static List xmlToGridElements(String string) { return xmlToDiagram(string).getGridElements(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/DiagramGwt.java0000644000175000017500000000636412533641120026562 0ustar benbenpackage com.baselet.gwt.client.element; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.baselet.control.config.SharedConfig; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.element.relation.Relation; import com.baselet.element.sticking.Stickable; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.Stickables; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.AutocompletionText; public class DiagramGwt implements Diagram { private static final Comparator LAYER_COMPARATOR_ASCENDING = new Comparator() { @Override public int compare(GridElement o1, GridElement o2) { return o1.getLayer().compareTo(o2.getLayer()); } }; private static final Comparator LAYER_COMPARATOR_DESCENDING = new Comparator() { @Override public int compare(GridElement o1, GridElement o2) { return o2.getLayer().compareTo(o1.getLayer()); } }; private String helpText; private final List gridElements; public DiagramGwt(List gridElements) { this(null, gridElements); } public DiagramGwt(String helpText, List gridElements) { super(); this.helpText = helpText; this.gridElements = gridElements; } @Override public List getGridElements() { return gridElements; } @Override public List getStickables() { List returnList = new ArrayList(); for (GridElement ge : gridElements) { if (ge instanceof Relation) { returnList.add((Relation) ge); } } return returnList; } @Override public StickableMap getStickables(GridElement draggedElement) { return getStickables(draggedElement, Collections. emptyList()); } @Override public StickableMap getStickables(GridElement draggedElement, Collection excludeList) { if (!SharedConfig.getInstance().isStickingEnabled()) { return StickableMap.EMPTY_MAP; } List stickables = getStickables(); stickables.removeAll(excludeList); StickingPolygon stickingBorder = draggedElement.generateStickingBorder(); StickableMap stickingStickables = Stickables.getStickingPointsWhichAreConnectedToStickingPolygon(stickingBorder, stickables); return stickingStickables; } @Override public List getGridElementsByLayerLowestToHighest() { return getGridElementsByLayer(true); } @Override public List getGridElementsByLayer(boolean ascending) { ArrayList list = new ArrayList<>(gridElements); if (ascending) { Collections.sort(list, LAYER_COMPARATOR_ASCENDING); } else { Collections.sort(list, LAYER_COMPARATOR_DESCENDING); } return list; } @Override public void setPanelAttributes(String panelAttributes) { helpText = panelAttributes; } @Override public String getPanelAttributes() { return helpText; } @Override public List getAutocompletionList() { return Collections. emptyList(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/BrowserStorage.java0000644000175000017500000000432712533641120027501 0ustar benbenpackage com.baselet.gwt.client.element; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import com.baselet.element.interfaces.GridElement; import com.google.gwt.storage.client.Storage; /** * uses local storage of browser * local storage calculator: http://glynrob.com/webapp/lscalc/ */ public class BrowserStorage { private static final String CLIPBOARD = "Clipboard"; private static final String SAVE_PREFIX = "s_"; private static Storage localStorage; public static boolean initLocalStorageAndCheckIfAvailable() { try { localStorage = Storage.getLocalStorageIfSupported(); return localStorage != null; } catch (Exception e) { return false; // Firefox with the Cookie setting "ask everytime" will throw an exception here! } } public static void addSavedDiagram(String name, String diagramXml) { set(SAVE_PREFIX + name, diagramXml); } public static void removeSavedDiagram(String chosenName) { remove(SAVE_PREFIX + chosenName); } public static String getSavedDiagram(String name) { return get(SAVE_PREFIX + name); } public static Collection getSavedDiagramKeys() { return getWithPrefix(SAVE_PREFIX, true).keySet(); } public static void setClipboard(List gridelements) { set(CLIPBOARD, DiagramXmlParser.gridElementsToXml(gridelements)); } public static List getClipboard() { return DiagramXmlParser.xmlToGridElements(get(CLIPBOARD)); } private static String get(String id) { return localStorage.getItem(id); } private static void remove(String id) { localStorage.removeItem(id); } private static Map getWithPrefix(String prefix, boolean removePrefixFromKey) { Map returnList = new HashMap(); for (int i = 0; i < localStorage.getLength(); i++) { String key = localStorage.key(i); if (key.startsWith(prefix)) { if (removePrefixFromKey) { key = key.substring(prefix.length()); } returnList.put(key, localStorage.getItem(key)); } } return returnList; } private static void set(String id, String value) { localStorage.setItem(id, value); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/element/ElementFactoryGwt.java0000644000175000017500000000330612533641120030130 0ustar benbenpackage com.baselet.gwt.client.element; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.ElementId; import com.baselet.element.NewGridElement; import com.baselet.element.elementnew.ElementFactory; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.DrawHandlerInterface; import com.baselet.element.interfaces.GridElement; import com.baselet.element.sticking.StickableMap; public class ElementFactoryGwt extends ElementFactory { public static GridElement create(ElementId id, Rectangle rect, String panelAttributes, String additionalPanelAttributes, final Diagram diagram) { final NewGridElement element = createAssociatedGridElement(id); DrawHandlerInterface handler = new DrawHandlerInterface() { @Override public void updatePropertyPanel() {} @Override public int getGridSize() { return SharedConstants.DEFAULT_GRID_SIZE; // GWT doesnt use own zoom implementation but relies on browser zoom } @Override public boolean isInitialized() { return true; // GWT initializes elements at once, therefore it's always initialized } @Override public StickableMap getStickableMap() { return diagram.getStickables(element); } }; element.init(rect, panelAttributes, additionalPanelAttributes, new ComponentGwt(element), handler); element.setPanelAttributes(panelAttributes); return element; } public static GridElement create(GridElement src, final Diagram targetDiagram) { return create(src.getId(), src.getRectangle().copy(), src.getPanelAttributes(), src.getAdditionalAttributes(), targetDiagram); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/base/0000755000175000017500000000000012533641120023141 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/base/Browser.java0000644000175000017500000000204412533641120025427 0ustar benbenpackage com.baselet.gwt.client.base; public enum Browser { INTERNET_EXPLORER("MSIE"), FIREFOX("Firefox"), CHROME("Chrome"), // also includes CHROME_ANDROID which would have browserFilters=["Android", "Chrome"] OPERA("Opera"), ANDROID_STOCK_BROWSER("Android"), // android chrome also have "Android" in its useragent but matches CHROME before coming here UNKNOWN("######"); private String[] browserFilters; private Browser(String... browserFilters) { this.browserFilters = browserFilters; } public static Browser get() { String currentAgent = getUserAgent(); for (Browser b : Browser.values()) { if (browserFiltersMatch(currentAgent, b)) { return b; } } return UNKNOWN; } private static boolean browserFiltersMatch(String currentAgent, Browser b) { for (String filterString : b.browserFilters) { if (!currentAgent.contains(filterString)) { return false; } } return true; } private final native static String getUserAgent() /*-{ return navigator.userAgent; }-*/; } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/base/Notification.java0000644000175000017500000000465212533641120026441 0ustar benbenpackage com.baselet.gwt.client.base; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.RootPanel; public class Notification { private static String lastShownFeatureNotSupportedText; private static Element element = RootPanel.get("featurewarning").getElement(); public static void showFeatureNotSupported(String text, boolean fadeOut) { if (text.equals(lastShownFeatureNotSupportedText)) { return; // don't repeat the last warning } lastShownFeatureNotSupportedText = text; element.getStyle().setColor("red"); element.setInnerHTML(text); if (fadeOut) { ElementFader.fade(element, 1, 0, 7000, 3000); } } public static void showInfo(String text) { element.getStyle().setColor("blue"); element.setInnerHTML(text); ElementFader.fade(element, 1, 0, 4000, 2000); } private static class ElementFader { private static int stepCount = 0; private static Timer timer; private static Timer timerFader; public synchronized static void fade(final Element element, final float startOpacity, final float endOpacity, final int delay, final int totalTimeMillis) { if (timer != null) { timer.cancel(); } if (timerFader != null) { timerFader.cancel(); } DOM.setStyleAttribute(element, "opacity", Float.toString(startOpacity));// set start opacity now to make sure the opacity of an interrupted previous timer is overwritten timer = new Timer() { @Override public void run() { fade(element, startOpacity, endOpacity, totalTimeMillis); } }; timer.schedule(delay); } private static void fade(final Element element, final float startOpacity, final float endOpacity, final int totalTimeMillis) { final int numberOfSteps = 30; int stepLengthMillis = totalTimeMillis / numberOfSteps; stepCount = 0; final float deltaOpacity = (endOpacity - startOpacity) / numberOfSteps; timerFader = new Timer() { @Override public void run() { float opacity = startOpacity + stepCount * deltaOpacity; DOM.setStyleAttribute(element, "opacity", Float.toString(opacity)); stepCount++; if (stepCount == numberOfSteps) { DOM.setStyleAttribute(element, "opacity", Float.toString(endOpacity)); cancel(); } } }; timerFader.scheduleRepeating(stepLengthMillis); } } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/base/Converter.java0000644000175000017500000000061612533641120025756 0ustar benbenpackage com.baselet.gwt.client.base; import com.baselet.diagram.draw.helper.ColorOwn; import com.google.gwt.canvas.dom.client.CssColor; public class Converter { public static CssColor convert(ColorOwn in) { if (in == null) { return null; } return CssColor.make("rgba(" + in.getRed() + ", " + in.getGreen() + "," + in.getBlue() + ", " + in.getAlpha() / 255.0 + ")"); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/base/Utils.java0000644000175000017500000000114712533641120025107 0ustar benbenpackage com.baselet.gwt.client.base; import com.google.gwt.dom.client.Style; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.ui.RootLayoutPanel; public class Utils { private static DateTimeFormat df = DateTimeFormat.getFormat("yyyy.MM.dd_HH:mm:ss"); public static void showCursor(Style.Cursor cursor) { RootLayoutPanel.get().getElement().getStyle().setCursor(cursor); } public static native String b64encode(String a) /*-{ return window.btoa(a); }-*/; public static native String b64decode(String a) /*-{ return window.atob(a); }-*/; } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/version/0000755000175000017500000000000012533641120023714 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/version/Build.properties0000644000175000017500000000020612533641120027067 0ustar benben#This file is automatically generated - DO NOT EDIT #Mon, 09 Feb 2015 21:30:27 +0100 buildtime=2015-02-09 21\:30 version=13.2 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/version/BuildProperties.java0000644000175000017500000000061412533641120027674 0ustar benbenpackage com.baselet.gwt.client.version; import com.google.gwt.core.client.GWT; public class BuildProperties { private static Build PROPERTIES = GWT.create(Build.class); public static String getVersionString() { return "Version: " + PROPERTIES.version() + "\nBuildTime: " + PROPERTIES.buildtime(); } public static String getVersion() { return PROPERTIES.version(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/version/Build.java0000644000175000017500000000026412533641120025620 0ustar benbenpackage com.baselet.gwt.client.version; import com.google.gwt.i18n.client.Constants; public interface Build extends Constants { String buildtime(); String version(); }umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/0000755000175000017500000000000012533641120023201 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/DrawCanvas.java0000644000175000017500000000670012533641120026100 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.List; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.enums.ElementId; import com.baselet.element.Selector; import com.baselet.element.interfaces.GridElement; import com.baselet.gwt.client.element.ComponentGwt; import com.baselet.gwt.client.element.ElementFactoryGwt; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.TextResource; import com.google.gwt.user.client.ui.FocusWidget; public class DrawCanvas { public interface HelptextResources extends ClientBundle { HelptextResources INSTANCE = GWT.create(HelptextResources.class); @Source("Helptext.txt") TextResource helpText(); } private final Canvas canvas = Canvas.createIfSupported(); public FocusWidget getWidget() { return canvas; } public Context2d getContext2d() { return canvas.getContext2d(); } public void clearAndSetSize(int width, int height) { // setCoordinateSpace always clears the canvas. To avoid that see https://groups.google.com/d/msg/google-web-toolkit/dpc84mHeKkA/3EKxrlyFCEAJ canvas.setCoordinateSpaceWidth(width); canvas.setCoordinateSpaceHeight(height); } public int getWidth() { return canvas.getCoordinateSpaceWidth(); } public int getHeight() { return canvas.getCoordinateSpaceHeight(); } public CanvasElement getCanvasElement() { return canvas.getCanvasElement(); } public String toDataUrl(String type) { return canvas.toDataUrl(type); } void draw(boolean drawEmptyInfo, List gridElements, Selector selector) { if (SharedConfig.getInstance().isDev_mode()) { CanvasUtils.drawGridOn(getContext2d()); } if (drawEmptyInfo && gridElements.isEmpty()) { drawEmptyInfoText(); } else { // if (tryOptimizedDrawing()) return; for (GridElement ge : gridElements) { ((ComponentGwt) ge.getComponent()).drawOn(canvas.getContext2d(), selector.isSelected(ge)); } } } private void drawEmptyInfoText() { double elWidth = 440; double elHeight = 150; double elXPos = getWidth() / 2.0 - elWidth / 2; double elYPos = getHeight() / 2.0 - elHeight; GridElement emptyElement = ElementFactoryGwt.create(ElementId.Text, new Rectangle(elXPos, elYPos, elWidth, elHeight), HelptextResources.INSTANCE.helpText().getText(), "", null); ((ComponentGwt) emptyElement.getComponent()).drawOn(canvas.getContext2d(), false); } // TODO would not work because canvas gets always resized and therefore cleaned -> so everything must be redrawn // private boolean tryOptimizedDrawing() { // List geToRedraw = new ArrayList(); // for (GridElement ge : gridElements) { // if(((GwtComponent) ge.getComponent()).isRedrawNecessary()) { // for (GridElement geRedraw : geToRedraw) { // if (geRedraw.getRectangle().intersects(ge.getRectangle())) { // return false; // } // } // geToRedraw.add(ge); // } // } // // for (GridElement ge : gridElements) { // elementCanvas.getContext2d().clearRect(0, 0, ge.getRectangle().getWidth(), ge.getRectangle().getHeight()); // ((GwtComponent) ge.getComponent()).drawOn(elementCanvas.getContext2d()); // } // return true; // } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/DrawPanel.java0000644000175000017500000004351312533641120025727 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.baselet.command.CommandTarget; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.MenuConstants; import com.baselet.control.constants.SharedConstants; import com.baselet.control.enums.Direction; import com.baselet.element.GridElementUtils; import com.baselet.element.Selector; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.element.sticking.StickableMap; import com.baselet.gwt.client.base.Utils; import com.baselet.gwt.client.element.DiagramGwt; import com.baselet.gwt.client.keyboard.Shortcut; import com.baselet.gwt.client.view.EventHandlingUtils.EventHandlingTarget; import com.baselet.gwt.client.view.interfaces.AutoresizeScrollDropTarget; import com.baselet.gwt.client.view.interfaces.HasScrollPanel; import com.baselet.gwt.client.view.widgets.MenuPopup; import com.baselet.gwt.client.view.widgets.MenuPopup.MenuPopupItem; import com.baselet.gwt.client.view.widgets.propertiespanel.PropertiesTextArea; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.HasMouseOutHandlers; import com.google.gwt.event.dom.client.HasMouseOverHandlers; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.SimplePanel; public abstract class DrawPanel extends SimplePanel implements CommandTarget, HasMouseOutHandlers, HasMouseOverHandlers, EventHandlingTarget, AutoresizeScrollDropTarget { private Diagram diagram = new DiagramGwt(new ArrayList()); protected DrawCanvas canvas = new DrawCanvas(); SelectorNew selector; CommandInvoker commandInvoker = CommandInvoker.getInstance(); DrawPanel otherDrawFocusPanel; HasScrollPanel scrollPanel; private final MainView mainView; PropertiesTextArea propertiesPanel; private final MenuPopup elementContextMenu; private final MenuPopup diagramContextMenu; private Set resizeDirection = new HashSet(); private final Map stickablesToMove = new HashMap(); public void setOtherDrawFocusPanel(DrawPanel otherDrawFocusPanel) { this.otherDrawFocusPanel = otherDrawFocusPanel; } private Boolean focus = false; @Override public void setFocus(boolean focus) { if (this.focus == focus) { return; } if (focus) { // if focus has switched from diagram <-> palette, reset other selector and redraw otherDrawFocusPanel.getSelector().deselectAllWithoutAfterAction(); otherDrawFocusPanel.redraw(); // redraw is necessary even if other afteractions (properties panel update) are not otherDrawFocusPanel.setFocus(false); } this.focus = focus; } public Boolean getFocus() { return focus; } public DrawPanel(final MainView mainView, final PropertiesTextArea propertiesPanel) { this.setStylePrimaryName("canvasFocusPanel"); this.mainView = mainView; this.propertiesPanel = propertiesPanel; selector = new SelectorNew(diagram) { @Override public void doAfterSelectionChanged() { updatePropertiesPanelWithSelectedElement(); } }; List diagramItems = Arrays.asList( new MenuPopupItem(MenuConstants.DELETE) { @Override public void execute() { commandInvoker.removeSelectedElements(DrawPanel.this); } }, new MenuPopupItem(MenuConstants.COPY) { @Override public void execute() { commandInvoker.copySelectedElements(DrawPanel.this); } }, new MenuPopupItem(MenuConstants.CUT) { @Override public void execute() { commandInvoker.cutSelectedElements(DrawPanel.this); } }, new MenuPopupItem(MenuConstants.PASTE) { @Override public void execute() { commandInvoker.pasteElements(DrawPanel.this); } }, new MenuPopupItem(MenuConstants.SELECT_ALL) { @Override public void execute() { selector.select(diagram.getGridElements()); } }); List elementItems = new ArrayList(diagramItems); elementItems.addAll(Arrays.asList( new MenuPopupItem(MenuConstants.GROUP) { @Override public void execute() { Integer unusedGroup = selector.getUnusedGroup(); commandInvoker.updateSelectedElementsProperty(DrawPanel.this, GroupFacet.KEY, unusedGroup); } }, new MenuPopupItem(MenuConstants.UNGROUP) { @Override public void execute() { commandInvoker.updateSelectedElementsProperty(DrawPanel.this, GroupFacet.KEY, null); } })); diagramContextMenu = new MenuPopup(diagramItems); elementContextMenu = new MenuPopup(elementItems); this.add(canvas.getWidget()); } @Override public void updatePropertiesPanelWithSelectedElement() { List elements = selector.getSelectedElements(); if (!elements.isEmpty()) { // always set properties text of latest selected element (so you also have an element in the prop panel even if you have an active multiselect) propertiesPanel.setGridElement(elements.get(elements.size() - 1), DrawPanel.this); } else { propertiesPanel.setGridElement(diagram, DrawPanel.this); } redraw(); } void keyboardMoveSelectedElements(int diffX, int diffY) { List gridElements = selector.getSelectedElements(); moveElements(diffX, diffY, true, gridElements); dragEndAndRedraw(gridElements); } void moveElements(int diffX, int diffY, boolean firstDrag, List elements) { if (elements.isEmpty()) { // if nothing is selected, move whole diagram elements = diagram.getGridElements(); } for (GridElement ge : elements) { if (firstDrag) { stickablesToMove.put(ge, getStickablesToMoveWhenElementsMove(ge, elements)); } ge.setRectangleDifference(diffX, diffY, 0, 0, firstDrag, stickablesToMove.get(ge), false); // uses setLocationDifference() instead of drag() to avoid special handling (eg: from Relations) } } @Override public Rectangle getVisibleBounds() { return scrollPanel.getVisibleBounds(); } @Override public void redraw() { redraw(true); } void redraw(boolean recalcSize) { List gridElements = diagram.getGridElementsByLayerLowestToHighest(); if (recalcSize) { if (scrollPanel == null) { return; } Rectangle diagramRect = GridElementUtils.getGridElementsRectangle(gridElements); Rectangle visibleRect = getVisibleBounds(); // realign top left corner of the diagram back to the canvas and remove invisible whitespace outside of the diagram final int xTranslate = Math.min(visibleRect.getX(), diagramRect.getX()); // can be positive (to cut upper left whitespace without diagram) or negative (to move diagram back to the visible canvas which starts at (0,0)) final int yTranslate = Math.min(visibleRect.getY(), diagramRect.getY()); if (xTranslate != 0 || yTranslate != 0) { // temp increase of canvas size to make sure scrollbar can be moved canvas.clearAndSetSize(canvas.getWidth() + Math.abs(xTranslate), canvas.getHeight() + Math.abs(yTranslate)); // move scrollbars scrollPanel.moveHorizontalScrollbar(-xTranslate); scrollPanel.moveVerticalScrollbar(-yTranslate); // then move gridelements to correct position for (GridElement ge : gridElements) { ge.setLocationDifference(-xTranslate, -yTranslate); } } // now realign bottom right corner to include the translate-factor and the changed visible and diagram rect int width = Math.max(visibleRect.getX2(), diagramRect.getX2()) - xTranslate; int height = Math.max(visibleRect.getY2(), diagramRect.getY2()) - yTranslate; canvas.clearAndSetSize(width, height); } else { canvas.clearAndSetSize(canvas.getWidth(), canvas.getHeight()); } canvas.draw(true, gridElements, selector); } @Override public GridElement getGridElementOnPosition(Point point) { GridElement returnGe = null; for (GridElement ge : diagram.getGridElementsByLayer(false)) { // get elements, highest layer first if (returnGe != null && returnGe.getLayer() > ge.getLayer()) { break; // because the following elements have lower layers, break if a valid higher layered element has been found } if (ge.isSelectableOn(point)) { if (returnGe == null) { returnGe = ge; } else { boolean newIsSelectedOldNot = selector.isSelected(ge) && !selector.isSelected(returnGe); boolean oldContainsNew = returnGe.getRectangle().contains(ge.getRectangle()); if (newIsSelectedOldNot || oldContainsNew) { returnGe = ge; } } } } return returnGe; } @Override public void setDiagram(Diagram diagram) { this.diagram = diagram; selector.setGridElementProvider(diagram); selector.deselectAll(); // necessary to trigger setting helptext to properties redraw(); } @Override public void addGridElements(List elements) { diagram.getGridElements().addAll(elements); selector.selectOnly(elements); } @Override public void removeGridElements(List elements) { diagram.getGridElements().removeAll(elements); selector.deselect(elements); } @Override public Diagram getDiagram() { return diagram; } @Override public Selector getSelector() { return selector; } @Override public void setAutoresizeScrollDrop(HasScrollPanel scrollPanel) { this.scrollPanel = scrollPanel; } @Override public abstract void onDoubleClick(GridElement ge); @Override public void onMouseDragEnd(GridElement gridElement, Point lastPoint) { dragEndAndRedraw(selector.getSelectedElements()); } private void dragEndAndRedraw(List selectedElements) { for (GridElement ge : selectedElements) { stickablesToMove.remove(ge); ge.dragEnd(); } redraw(); } @Override public void onMouseDownScheduleDeferred(final GridElement element, final boolean isControlKeyDown) { Scheduler.get().scheduleFinally(new ScheduledCommand() { // scheduleDeferred is necessary for mobile (or low performance) browsers @Override public void execute() { onMouseDown(element, isControlKeyDown); } }); } void onMouseDown(final GridElement element, final boolean isControlKeyDown) { if (isControlKeyDown) { if (element != null) { if (selector.isSelected(element)) { selector.deselect(element); } else { selector.select(element); } } } else { if (element != null) { if (selector.isSelected(element)) { selector.moveToLastPosInList(element); propertiesPanel.setGridElement(element, DrawPanel.this); } else { selector.selectOnly(element); } } else { selector.deselectAll(); } } } @Override public void onMouseMoveDraggingScheduleDeferred(final Point dragStart, final int diffX, final int diffY, final GridElement draggedGridElement, final boolean isShiftKeyDown, final boolean isCtrlKeyDown, final boolean firstDrag) { Scheduler.get().scheduleFinally(new ScheduledCommand() { // scheduleDeferred is necessary for mobile (or low performance) browsers @Override public void execute() { onMouseMoveDragging(dragStart, diffX, diffY, draggedGridElement, isShiftKeyDown, isCtrlKeyDown, firstDrag); } }); } void onMouseMoveDragging(Point dragStart, int diffX, int diffY, GridElement draggedGridElement, boolean isShiftKeyDown, boolean isCtrlKeyDown, boolean firstDrag) { if (firstDrag && draggedGridElement != null) { // if draggedGridElement == null the whole diagram is dragged and nothing has to be checked for sticking stickablesToMove.put(draggedGridElement, getStickablesToMoveWhenElementsMove(draggedGridElement, Collections. emptyList())); } if (isCtrlKeyDown) { return; // TODO implement Lasso } else if (!resizeDirection.isEmpty()) { draggedGridElement.drag(resizeDirection, diffX, diffY, getRelativePoint(dragStart, draggedGridElement), isShiftKeyDown, firstDrag, stickablesToMove.get(draggedGridElement), false); } // if a single element is selected, drag it (and pass the dragStart, because it's important for Relations) else if (selector.getSelectedElements().size() == 1) { draggedGridElement.drag(Collections. emptySet(), diffX, diffY, getRelativePoint(dragStart, draggedGridElement), isShiftKeyDown, firstDrag, stickablesToMove.get(draggedGridElement), false); } else { // if != 1 elements are selected, move them moveElements(diffX, diffY, firstDrag, selector.getSelectedElements()); } redraw(false); } private Point getRelativePoint(Point dragStart, GridElement draggedGridElement) { return new Point(dragStart.getX() - draggedGridElement.getRectangle().getX(), dragStart.getY() - draggedGridElement.getRectangle().getY()); } protected StickableMap getStickablesToMoveWhenElementsMove(GridElement draggedElement, List excludeList) { return diagram.getStickables(draggedElement, excludeList); } @Override public void onMouseMove(Point absolute) { GridElement geOnPosition = getGridElementOnPosition(absolute); if (geOnPosition != null) { // exactly one gridelement selected which is at the mouseposition resizeDirection = geOnPosition.getResizeArea(absolute.getX() - geOnPosition.getRectangle().getX(), absolute.getY() - geOnPosition.getRectangle().getY()); if (resizeDirection.isEmpty()) { Utils.showCursor(Style.Cursor.POINTER); // HAND Cursor } else if (resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.RIGHT)) { Utils.showCursor(Style.Cursor.NE_RESIZE); } else if (resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.LEFT)) { Utils.showCursor(Style.Cursor.NW_RESIZE); } else if (resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.LEFT)) { Utils.showCursor(Style.Cursor.SW_RESIZE); } else if (resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.RIGHT)) { Utils.showCursor(Style.Cursor.SE_RESIZE); } else if (resizeDirection.contains(Direction.UP)) { Utils.showCursor(Style.Cursor.N_RESIZE); } else if (resizeDirection.contains(Direction.RIGHT)) { Utils.showCursor(Style.Cursor.E_RESIZE); } else if (resizeDirection.contains(Direction.DOWN)) { Utils.showCursor(Style.Cursor.S_RESIZE); } else if (resizeDirection.contains(Direction.LEFT)) { Utils.showCursor(Style.Cursor.W_RESIZE); } } else { resizeDirection.clear(); Utils.showCursor(Style.Cursor.MOVE); } } @Override public void onShowMenu(Point point) { Point relativePoint = new Point(point.x - getAbsoluteLeft(), point.y - getAbsoluteTop()); if (getGridElementOnPosition(relativePoint) == null) { // gridelement check must be made with relative coordinates diagramContextMenu.show(point); } else { elementContextMenu.show(point); } } @Override public void handleKeyDown(KeyDownEvent event) { boolean avoidBrowserDefault = true; if (Shortcut.DELETE_ELEMENT.matches(event)) { commandInvoker.removeSelectedElements(DrawPanel.this); } else if (Shortcut.DESELECT_ALL.matches(event)) { selector.deselectAll(); } else if (Shortcut.SELECT_ALL.matches(event)) { selector.select(diagram.getGridElements()); } else if (Shortcut.COPY.matches(event)) { commandInvoker.copySelectedElements(DrawPanel.this); } else if (Shortcut.CUT.matches(event)) { commandInvoker.cutSelectedElements(DrawPanel.this); } else if (Shortcut.PASTE.matches(event)) { commandInvoker.pasteElements(DrawPanel.this); } else if (Shortcut.SAVE.matches(event)) { mainView.getSaveCommand().execute(); } else if (Shortcut.MOVE_UP.matches(event)) { keyboardMoveSelectedElements(0, -SharedConstants.DEFAULT_GRID_SIZE); redraw(); } else if (Shortcut.MOVE_DOWN.matches(event)) { keyboardMoveSelectedElements(0, SharedConstants.DEFAULT_GRID_SIZE); redraw(); } else if (Shortcut.MOVE_LEFT.matches(event)) { keyboardMoveSelectedElements(-SharedConstants.DEFAULT_GRID_SIZE, 0); redraw(); } else if (Shortcut.MOVE_RIGHT.matches(event)) { keyboardMoveSelectedElements(SharedConstants.DEFAULT_GRID_SIZE, 0); redraw(); } else if (Shortcut.DISABLE_STICKING.matches(event)) { SharedConfig.getInstance().setStickingEnabled(false); } else { avoidBrowserDefault = false; } // avoid browser default key handling for all overwritten keys, but not for others (like F5 for refresh or the zoom controls) if (avoidBrowserDefault) { event.preventDefault(); } } @Override public void handleKeyUp(KeyUpEvent event) { if (Shortcut.DISABLE_STICKING.matches(event)) { SharedConfig.getInstance().setStickingEnabled(true); } } @Override public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) { return addDomHandler(handler, MouseOverEvent.getType()); } @Override public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) { return addDomHandler(handler, MouseOutEvent.getType()); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/DrawPanelDiagram.java0000644000175000017500000000160412533641120027207 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.Arrays; import com.baselet.control.constants.SharedConstants; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.gwt.client.element.ElementFactoryGwt; import com.baselet.gwt.client.view.widgets.propertiespanel.PropertiesTextArea; public class DrawPanelDiagram extends DrawPanel { public DrawPanelDiagram(MainView mainView, PropertiesTextArea propertiesPanel) { super(mainView, propertiesPanel); } @Override public void onDoubleClick(GridElement ge) { if (ge != null) { GridElement e = ElementFactoryGwt.create(ge, getDiagram()); e.setProperty(GroupFacet.KEY, null); e.setLocationDifference(SharedConstants.DEFAULT_GRID_SIZE, SharedConstants.DEFAULT_GRID_SIZE); commandInvoker.addElements(this, Arrays.asList(e)); } } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/EventHandlingUtils.java0000644000175000017500000003336412533641120027624 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.element.interfaces.GridElement; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.ContextMenuEvent; import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DoubleClickHandler; import com.google.gwt.event.dom.client.HumanInputEvent; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseEvent; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.TouchEndEvent; import com.google.gwt.event.dom.client.TouchEndHandler; import com.google.gwt.event.dom.client.TouchEvent; import com.google.gwt.event.dom.client.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchMoveHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.FocusPanel; public class EventHandlingUtils { private static final List DRAG_COMMANDS = Arrays.asList(DragStatus.FIRST, DragStatus.CONTINUOUS); public static interface EventHandlingTarget { HandlerRegistration addMouseOutHandler(MouseOutHandler mouseOutHandler); HandlerRegistration addMouseOverHandler(MouseOverHandler mouseOverHandler); void handleKeyDown(KeyDownEvent event); void handleKeyUp(KeyUpEvent event); void onMouseMoveDraggingScheduleDeferred(Point moveStart, int diffX, int diffY, GridElement elementToDrag, boolean shiftKeyDown, boolean controlKeyDown, boolean b); void onMouseMove(Point point); void onMouseDragEnd(GridElement elementToDrag, Point point); void onMouseDownScheduleDeferred(GridElement elementToDrag, boolean controlKeyDown); void onDoubleClick(GridElement gridElementOnPosition); void onShowMenu(Point p); Rectangle getVisibleBounds(); int getAbsoluteLeft(); int getAbsoluteTop(); void setFocus(boolean b); GridElement getGridElementOnPosition(Point p); Element getElement(); } private static enum DragStatus { FIRST, CONTINUOUS, NO } private static class DragCache { private DragStatus dragging = DragStatus.NO; private Point moveStart; private GridElement elementToDrag; private EventHandlingTarget activePanel; private EventHandlingTarget mouseContainingPanel; private List nonTouchHandlers = new ArrayList(); /** * doubleclicks are only handled if the mouse has moved into the canvas before * this is necessary to void unwanted propagation of suggestbox-selections via doubleclick * TODO: a better fix would be a custom SuggestDisplay which stops mouseevent propagation after handling them */ private boolean doubleClickEnabled = true; // private Timer menuShowTimer; //TODO doesn't really work at the moment (because some move and end events are not processed, therefore it's shown even if not wanted) } public static void addEventHandler(final FocusPanel handlerTarget, final EventHandlingTarget... panels) { final DragCache storage = new DragCache(); for (final EventHandlingTarget panel : panels) { storage.nonTouchHandlers.add(panel.addMouseOutHandler(new MouseOutHandler() { @Override public void onMouseOut(MouseOutEvent event) { storage.mouseContainingPanel = null; } })); storage.nonTouchHandlers.add(panel.addMouseOverHandler(new MouseOverHandler() { @Override public void onMouseOver(MouseOverEvent event) { storage.mouseContainingPanel = panel; } })); } handlerTarget.addTouchStartHandler(new TouchStartHandler() { @Override public void onTouchStart(final TouchStartEvent event) { // some mouseevents are interfering with touch events (eg: mousemove is triggered on each touchdown event) therefore they are removed as soon as a touch event is detected if (storage.nonTouchHandlers != null) { for (HandlerRegistration h : storage.nonTouchHandlers) { h.removeHandler(); } storage.nonTouchHandlers = null; } if (event.getTouches().length() == 1) { // only handle single finger touches (to allow zooming with 2 fingers) final Point absolutePos = getPointAbsolute(event); storage.activePanel = getPanelWhichContainsPoint(panels, absolutePos); if (storage.activePanel != null) { handleStart(panels, storage, handlerTarget, event, getPoint(storage.activePanel, event)); } // storage.menuShowTimer = new Timer() { // @Override // public void run() { // handleShowMenu(storage.activePanel, absolutePos); // } // }; // storage.menuShowTimer.schedule(1000); } } }); handlerTarget.addTouchEndHandler(new TouchEndHandler() { @Override public void onTouchEnd(TouchEndEvent event) { // storage.menuShowTimer.cancel(); if (storage.activePanel != null) { handleEnd(storage.activePanel, storage, event); } } }); handlerTarget.addTouchMoveHandler(new TouchMoveHandler() { @Override public void onTouchMove(TouchMoveEvent event) { // storage.menuShowTimer.cancel(); if (event.getTouches().length() == 1) { // only handle single finger touches (to allow zooming with 2 fingers) handleMove(storage.activePanel, storage, event); } } }); storage.nonTouchHandlers.add(handlerTarget.addMouseDownHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { storage.activePanel = getPanelWhichContainsPoint(panels, getPointAbsolute(event)); if (storage.activePanel != null) { handleStart(panels, storage, handlerTarget, event, getPoint(storage.activePanel, event)); } } })); storage.nonTouchHandlers.add(handlerTarget.addMouseUpHandler(new MouseUpHandler() { @Override public void onMouseUp(MouseUpEvent event) { if (storage.activePanel != null) { handleEnd(storage.activePanel, storage, event); } } })); storage.nonTouchHandlers.add(handlerTarget.addMouseOutHandler(new MouseOutHandler() { @Override public void onMouseOut(MouseOutEvent event) { if (storage.activePanel != null) { handleEnd(storage.activePanel, storage, event); storage.doubleClickEnabled = false; } } })); storage.nonTouchHandlers.add(handlerTarget.addMouseOverHandler(new MouseOverHandler() { @Override public void onMouseOver(MouseOverEvent event) { storage.doubleClickEnabled = true; } })); storage.nonTouchHandlers.add(handlerTarget.addMouseMoveHandler(new MouseMoveHandler() { @Override public void onMouseMove(MouseMoveEvent event) { handleMove(storage.activePanel, storage, event); } })); // double tap on mobile devices is not easy to implement because browser zoom on double-tap is not an event which can be canceled storage.nonTouchHandlers.add(handlerTarget.addDoubleClickHandler(new DoubleClickHandler() { @Override public void onDoubleClick(DoubleClickEvent event) { if (storage.activePanel != null) { if (storage.doubleClickEnabled) { handleDoubleClick(storage.activePanel, getPoint(storage.activePanel, event)); } } } })); storage.nonTouchHandlers.add(handlerTarget.addDomHandler(new ContextMenuHandler() { @Override public void onContextMenu(ContextMenuEvent event) { if (storage.activePanel != null) { event.preventDefault(); // avoid default contextmenu event.stopPropagation(); handleShowMenu(storage.activePanel, new Point(event.getNativeEvent().getClientX(), event.getNativeEvent().getClientY())); } } }, ContextMenuEvent.getType())); storage.nonTouchHandlers.add(handlerTarget.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (storage.activePanel != null) { storage.activePanel.handleKeyDown(event); } } })); storage.nonTouchHandlers.add(handlerTarget.addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { if (storage.activePanel != null) { storage.activePanel.handleKeyUp(event); } } })); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { handlerTarget.setFocus(true); // set focus to enable keyboard shortcuts } }); } private static void handleEnd(EventHandlingTarget panel, final DragCache storage, HumanInputEvent event) { // Notification.showInfo("UP"); if (DRAG_COMMANDS.contains(storage.dragging)) { panel.onMouseDragEnd(storage.elementToDrag, getPoint(storage.activePanel, event)); } storage.dragging = DragStatus.NO; } private static void handleStart(EventHandlingTarget[] panels, final DragCache storage, FocusPanel handlerTarget, HumanInputEvent event, Point p) { // Notification.showInfo("DOWN " + p.x); handlerTarget.setFocus(true); event.preventDefault(); // necessary to avoid showing textcursor and selecting proppanel in chrome AND to avoid scrolling with touch move (problem is it also avoids scrolling with 2 fingers) storage.moveStart = new Point(p.x, p.y); storage.dragging = DragStatus.FIRST; storage.elementToDrag = storage.activePanel.getGridElementOnPosition(storage.moveStart); storage.activePanel.onMouseDownScheduleDeferred(storage.elementToDrag, event.isControlKeyDown()); } private static void handleMove(final EventHandlingTarget panel, final DragCache storage, HumanInputEvent event) { // Notification.showInfo("MOVE " + getPointAbsolute(event)); if (storage.activePanel != null && DRAG_COMMANDS.contains(storage.dragging)) { Point p = getPoint(storage.activePanel, event); int diffX = p.x - storage.moveStart.getX(); int diffY = p.y - storage.moveStart.getY(); diffX -= diffX % SharedConstants.DEFAULT_GRID_SIZE; diffY -= diffY % SharedConstants.DEFAULT_GRID_SIZE; if (diffX != 0 || diffY != 0) { panel.onMouseMoveDraggingScheduleDeferred(storage.moveStart, diffX, diffY, storage.elementToDrag, event.isShiftKeyDown(), event.isControlKeyDown(), storage.dragging == DragStatus.FIRST); storage.dragging = DragStatus.CONTINUOUS; // after FIRST real drag switch to CONTINUOUS storage.moveStart = storage.moveStart.copy().move(diffX, diffY); // make copy because otherwise deferred action will act on wrong position } } else if (storage.mouseContainingPanel != null) { storage.mouseContainingPanel.onMouseMove(getPoint(storage.mouseContainingPanel, event)); } } private static void handleDoubleClick(final EventHandlingTarget panel, Point p) { panel.onDoubleClick(panel.getGridElementOnPosition(p)); } private static void handleShowMenu(final EventHandlingTarget panel, Point p) { panel.onShowMenu(p); } private static EventHandlingTarget getPanelWhichContainsPoint(EventHandlingTarget[] panels, Point p) { EventHandlingTarget returnPanel = null; for (EventHandlingTarget panel : panels) { Rectangle visibleBounds = panel.getVisibleBounds(); visibleBounds.move(panel.getAbsoluteLeft(), panel.getAbsoluteTop()); if (visibleBounds.contains(p)) { panel.setFocus(true); returnPanel = panel; } else { panel.setFocus(false); } } return returnPanel; } private static Point getPoint(EventHandlingTarget drawPanelCanvas, HumanInputEvent event) { Element e = drawPanelCanvas.getElement(); if (event instanceof MouseEvent) { return new Point(((MouseEvent) event).getRelativeX(e), ((MouseEvent) event).getRelativeY(e)); } else if (event instanceof TouchEndEvent) { return new Point(((TouchEvent) event).getChangedTouches().get(0).getRelativeX(e), ((TouchEvent) event).getChangedTouches().get(0).getRelativeY(e)); } else if (event instanceof TouchEvent) { return new Point(((TouchEvent) event).getTouches().get(0).getRelativeX(e), ((TouchEvent) event).getTouches().get(0).getRelativeY(e)); } else { throw new RuntimeException("Unknown Event Type: " + event); } } private static Point getPointAbsolute(HumanInputEvent event) { if (event instanceof MouseEvent) { return new Point(((MouseEvent) event).getClientX(), ((MouseEvent) event).getClientY()); } else if (event instanceof TouchEndEvent) { return new Point(((TouchEvent) event).getChangedTouches().get(0).getPageX(), ((TouchEvent) event).getChangedTouches().get(0).getPageY()); } else if (event instanceof TouchEvent) { return new Point(((TouchEvent) event).getTouches().get(0).getPageX(), ((TouchEvent) event).getTouches().get(0).getPageY()); } else { throw new RuntimeException("Unknown Event Type: " + event); } } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/0000755000175000017500000000000012533641120024300 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/0000755000175000017500000000000012533641120025760 5ustar benben././@LongLink0000644000000000000000000000016500000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/AutoResizeScrollDropPanel.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/AutoResizeScro0000644000175000017500000001042712533641120030630 0ustar benbenpackage com.baselet.gwt.client.view.panel.wrapper; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Rectangle; import com.baselet.gwt.client.base.Browser; import com.baselet.gwt.client.view.interfaces.AutoresizeScrollDropTarget; import com.baselet.gwt.client.view.interfaces.HasScrollPanel; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.ScrollPanel; public class AutoResizeScrollDropPanel extends ScrollPanel implements HasScrollPanel { private final FileDropPanel dropPanel; public AutoResizeScrollDropPanel(final AutoresizeScrollDropTarget diagram) { setAlwaysShowScrollBars(true); // must be set otherwise elements can "jump around" (eg: empty diagram, class outside of top of diagram, click multiple times on diagram -> class jumps back to diagram) diagram.setAutoresizeScrollDrop(this); dropPanel = new FileDropPanel(diagram); this.add(dropPanel); // update size after initialization of gui has finished Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { diagram.redraw(); } }); // also update size everytime the mouse has been released on the scrollbar or the window has been resized // MouseUpHandler handler = new MouseUpHandler() { // @Override // public void onMouseUp(MouseUpEvent event) { // diagram.redraw(); // } // }; // getHorizontalScrollbar().asWidget().addDomHandler(handler, MouseUpEvent.getType()); // getVerticalScrollbar().asWidget().addDomHandler(handler, MouseUpEvent.getType()); Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { diagram.redraw(); } }); } @Override public Rectangle getVisibleBounds() { int width = getOffsetWidth() - getScrollbarSize()[0]; int height = getOffsetHeight() - getScrollbarSize()[1]; if (Browser.get() == Browser.FIREFOX || Browser.get() == Browser.INTERNET_EXPLORER) { height -= 4; // if too low, the "scroll down" arrow of the vertical scrollbar will never stop moving the diagram and the scrollbar is always visible, if too high, elements will move down if user clicks on the diagram } else { height -= 3; // if too low, the "scroll down" arrow of the vertical scrollbar will never stop moving the diagram and the scrollbar is always visible, if too high, elements will move down if user clicks on the diagram } return new Rectangle(getHorizontalScrollPosition(), getVerticalScrollPosition(), width, height); } @Override public void moveHorizontalScrollbar(int diff) { setHorizontalScrollPosition(getHorizontalScrollPosition() + diff); } @Override public void moveVerticalScrollbar(int diff) { setVerticalScrollPosition(getVerticalScrollPosition() + diff); } private int[] scrollbarSize; /** * returns vertical scrollbar width and horizontal scrollbar height * IGNORES ZOOM LEVEL AT THE MOMENT!! */ public int[] getScrollbarSize() { if (scrollbarSize == null) { String[] split = getScrollbarSizeHelper().split(" "); scrollbarSize = new int[] { Integer.parseInt(split[0]), Integer.parseInt(split[1]) }; } return SharedUtils.cloneArray(scrollbarSize); } private final native static String getScrollbarSizeHelper() /*-{ var inner = document.createElement('p'); inner.style.width = "100%"; inner.style.height = "100%"; var outer = document.createElement('div'); outer.style.position = "absolute"; outer.style.top = "0px"; outer.style.left = "0px"; outer.style.visibility = "hidden"; outer.style.width = "100px"; outer.style.height = "100px"; outer.style.overflow = "hidden"; outer.appendChild(inner); document.body.appendChild(outer); var w1 = inner.offsetWidth; var h1 = inner.offsetHeight; outer.style.overflow = 'scroll'; var w2 = inner.offsetWidth; var h2 = inner.offsetHeight; if (w1 == w2) w2 = outer.clientWidth; if (h1 == h2) h2 = outer.clientHeight; document.body.removeChild(outer); return (w1 - w2) + " " + (h1 - h2); }-*/; } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/FileDropPanel.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/FileDropPanel.0000644000175000017500000000346212533641120030452 0ustar benbenpackage com.baselet.gwt.client.view.panel.wrapper; import org.vectomatic.dnd.DataTransferExt; import org.vectomatic.dnd.DropPanel; import org.vectomatic.file.FileList; import com.baselet.gwt.client.view.interfaces.AutoresizeScrollDropTarget; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.DragEnterEvent; import com.google.gwt.event.dom.client.DragEnterHandler; import com.google.gwt.event.dom.client.DragLeaveEvent; import com.google.gwt.event.dom.client.DragLeaveHandler; import com.google.gwt.event.dom.client.DragOverEvent; import com.google.gwt.event.dom.client.DragOverHandler; import com.google.gwt.event.dom.client.DropEvent; import com.google.gwt.event.dom.client.DropHandler; public class FileDropPanel extends DropPanel { private final FileOpenHandler handler; public FileDropPanel(final AutoresizeScrollDropTarget diagram) { this.add(diagram); handler = new FileOpenHandler(diagram); addDragOverHandler(new DragOverHandler() { @Override public void onDragOver(DragOverEvent event) { avoidDefaultHandling(event); } }); addDragEnterHandler(new DragEnterHandler() { @Override public void onDragEnter(DragEnterEvent event) { avoidDefaultHandling(event); } }); addDragLeaveHandler(new DragLeaveHandler() { @Override public void onDragLeave(DragLeaveEvent event) { avoidDefaultHandling(event); } }); addDropHandler(new DropHandler() { @Override public void onDrop(DropEvent event) { FileList files = event.getDataTransfer(). cast().getFiles(); handler.processFiles(files); avoidDefaultHandling(event); } }); } private void avoidDefaultHandling(DomEvent event) { event.stopPropagation(); event.preventDefault(); } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/FileOpenHandler.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/panel/wrapper/FileOpenHandle0000644000175000017500000000446512533641120030531 0ustar benbenpackage com.baselet.gwt.client.view.panel.wrapper; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.vectomatic.file.ErrorCode; import org.vectomatic.file.File; import org.vectomatic.file.FileError; import org.vectomatic.file.FileList; import org.vectomatic.file.FileReader; import org.vectomatic.file.events.LoadEndEvent; import org.vectomatic.file.events.LoadEndHandler; import com.baselet.gwt.client.element.DiagramXmlParser; import com.baselet.gwt.client.view.interfaces.AcceptDiagram; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Window; public class FileOpenHandler { private final Logger log = Logger.getLogger(FileOpenHandler.class); protected FileReader reader; protected List readQueue = new ArrayList(); public FileOpenHandler(final AcceptDiagram diagram) { reader = new FileReader(); reader.addLoadEndHandler(new LoadEndHandler() { @Override public void onLoadEnd(LoadEndEvent event) { if (reader.getError() == null) { if (readQueue.size() > 0) { try { String result = reader.getStringResult(); diagram.setDiagram(DiagramXmlParser.xmlToDiagram(result)); } catch (RuntimeException e) { log.error("Error at loading diagram from file", e); } finally { readQueue.remove(0); readNext(); } } } } }); } public void processFiles(FileList files) { GWT.log("length=" + files.getLength()); for (File file : files) { readQueue.add(file); } readNext(); } private void readNext() { if (readQueue.size() > 0) { File file = readQueue.get(0); try { reader.readAsText(file); } catch (Throwable t) { // Necessary for FF (see bug https://bugzilla.mozilla.org/show_bug.cgi?id=701154) // Standard-complying browsers will to go in this branch handleError(file); readQueue.remove(0); readNext(); } } } private void handleError(File file) { FileError error = reader.getError(); String errorDesc = ""; if (error != null) { ErrorCode errorCode = error.getCode(); if (errorCode != null) { errorDesc = ": " + errorCode.name(); } } Window.alert("File loading error for file: " + file.getName() + "\n" + errorDesc); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/0000755000175000017500000000000012533641120025324 5ustar benben././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/AcceptDiagram.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/AcceptDiagram.jav0000644000175000017500000000026512533641120030515 0ustar benbenpackage com.baselet.gwt.client.view.interfaces; import com.baselet.element.interfaces.Diagram; public interface AcceptDiagram { void setDiagram(Diagram xmlToDiagram); } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/HasScrollPanel.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/HasScrollPanel.ja0000644000175000017500000000051612533641120030514 0ustar benbenpackage com.baselet.gwt.client.view.interfaces; import com.baselet.control.basics.geom.Rectangle; public interface HasScrollPanel { Rectangle getVisibleBounds(); void moveHorizontalScrollbar(int i); void moveVerticalScrollbar(int i); int getVerticalScrollPosition(); int getHorizontalScrollPosition(); } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/Redrawable.java0000644000175000017500000000014612533641120030240 0ustar benbenpackage com.baselet.gwt.client.view.interfaces; public interface Redrawable { void redraw(); } ././@LongLink0000644000000000000000000000016300000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/AutoresizeScrollDropTarget.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/interfaces/AutoresizeScrollD0000644000175000017500000000041712533641120030666 0ustar benbenpackage com.baselet.gwt.client.view.interfaces; import com.google.gwt.user.client.ui.IsWidget; public interface AutoresizeScrollDropTarget extends IsWidget, AcceptDiagram, Redrawable { void setAutoresizeScrollDrop(HasScrollPanel autoResizeScrollDropPanel); }umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/CommandInvoker.java0000644000175000017500000000624312533641120026765 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.ArrayList; import java.util.Collection; import java.util.List; import com.baselet.command.AddGridElementCommand; import com.baselet.command.CommandTarget; import com.baselet.command.Controller; import com.baselet.command.RemoveGridElementCommand; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.element.GridElementUtils; import com.baselet.element.Selector; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.gwt.client.element.BrowserStorage; import com.baselet.gwt.client.element.ElementFactoryGwt; public class CommandInvoker extends Controller { private static final CommandInvoker instance = new CommandInvoker(); public static CommandInvoker getInstance() { return instance; } private CommandInvoker() { super(); } void addElements(CommandTarget target, List elements) { executeCommand(new AddGridElementCommand(target, elements)); } void removeElements(CommandTarget target, List elements) { executeCommand(new RemoveGridElementCommand(target, elements)); } void removeSelectedElements(CommandTarget target) { removeElements(target, target.getSelector().getSelectedElements()); } // TODO implement copy & paste as commands void copySelectedElements(CommandTarget target) { BrowserStorage.setClipboard(copyElementsInList(target.getSelector().getSelectedElements(), target.getDiagram())); // must be copied here to ensure location etc. will not be changed } void cutSelectedElements(CommandTarget target) { copySelectedElements(target); removeSelectedElements(target); } void pasteElements(CommandTarget target) { List copyOfElements = copyElementsInList(BrowserStorage.getClipboard(), target.getDiagram()); Selector.replaceGroupsWithNewGroups(copyOfElements, target.getSelector()); realignElementsToVisibleRect(target, copyOfElements); addElements(target, copyOfElements); // copy here to make sure it can be pasted multiple times } private List copyElementsInList(Collection sourceElements, Diagram targetDiagram) { List targetElements = new ArrayList(); for (GridElement ge : sourceElements) { GridElement e = ElementFactoryGwt.create(ge, targetDiagram); targetElements.add(e); } return targetElements; } void realignElementsToVisibleRect(CommandTarget target, List gridElements) { Rectangle rect = GridElementUtils.getGridElementsRectangle(gridElements); Rectangle visible = target.getVisibleBounds(); for (GridElement ge : gridElements) { ge.getRectangle().move(visible.getX() - rect.getX() + SharedConstants.DEFAULT_GRID_SIZE, visible.getY() - rect.getY() + SharedConstants.DEFAULT_GRID_SIZE); } } public void updateSelectedElementsProperty(CommandTarget target, String key, Object value) { for (GridElement e : target.getSelector().getSelectedElements()) { e.setProperty(key, value); } target.updatePropertiesPanelWithSelectedElement(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/CanvasUtils.java0000644000175000017500000000526612533641120026311 0ustar benbenpackage com.baselet.gwt.client.view; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.SharedConstants; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.GridElementUtils; import com.baselet.element.interfaces.Diagram; import com.baselet.gwt.client.base.Converter; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; public class CanvasUtils { private static final int EXPORT_BORDER = 10; public static String createPngCanvasDataUrl(Diagram diagram) { DrawCanvas pngCanvas = new DrawCanvas(); // Calculate and set canvas width Rectangle geRect = GridElementUtils.getGridElementsRectangle(diagram.getGridElements()); geRect.addBorder(EXPORT_BORDER); pngCanvas.clearAndSetSize(geRect.getWidth(), geRect.getHeight()); // Fill Canvas white pngCanvas.getContext2d().setFillStyle(Converter.convert(ColorOwn.WHITE)); pngCanvas.getContext2d().fillRect(0, 0, pngCanvas.getWidth(), pngCanvas.getHeight()); // Draw Elements on Canvas and translate their position pngCanvas.getContext2d().translate(-geRect.getX(), -geRect.getY()); pngCanvas.draw(false, diagram.getGridElementsByLayerLowestToHighest(), new SelectorNew(diagram)); // use a new selector which has nothing selected return pngCanvas.toDataUrl("image/png"); } private static Canvas gridCanvas; public static void drawGridOn(Context2d context2d) { if (gridCanvas == null) { gridCanvas = Canvas.createIfSupported(); gridCanvas.setCoordinateSpaceWidth(3000); gridCanvas.setCoordinateSpaceHeight(2000); int width = gridCanvas.getCoordinateSpaceWidth(); int height = gridCanvas.getCoordinateSpaceHeight(); Context2d backgroundContext = gridCanvas.getContext2d(); backgroundContext.setStrokeStyle(Converter.convert(ColorOwn.BLACK.transparency(Transparency.SELECTION_BACKGROUND))); for (int i = 0; i < width; i += SharedConstants.DEFAULT_GRID_SIZE) { drawLine(backgroundContext, i, 0, i, height); } for (int i = 0; i < height; i += SharedConstants.DEFAULT_GRID_SIZE) { drawLine(backgroundContext, 0, i, width, i); } } context2d.drawImage(gridCanvas.getCanvasElement(), 0, 0); } private static void drawLine(Context2d context, int x, int y, int x2, int y2) { context.beginPath(); context.moveTo(x + 0.5, y + 0.5); // +0.5 because a line of thickness 1.0 spans 50% left and 50% right (therefore it would not be on the 1 pixel - see https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Applying_styles_and_colors) context.lineTo(x2 + 0.5, y2 + 0.5); context.stroke(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/MainView.ui.xml0000644000175000017500000001422212533641120026057 0ustar benben .image { cursor: help; } .version { font-weight: bold; font-size: 0.85em; text-align: center; } .menuItem { padding-left: 0.3em; font-size: 0.9em; } .menuItem:hover { background: #E3E8F3; cursor: pointer; } .propertiesTitle { padding-left: 0.5em; font-size: 0.85em; font-weight: bold; background-color: #E7E7E7; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; }


Properties
umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/DrawPanelPalette.java0000644000175000017500000001250212533641120027240 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import com.baselet.control.SharedUtils; import com.baselet.control.basics.geom.Point; import com.baselet.element.Selector; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.Diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.element.sticking.StickableMap; import com.baselet.gwt.client.element.DiagramXmlParser; import com.baselet.gwt.client.element.ElementFactoryGwt; import com.baselet.gwt.client.view.palettes.Resources; import com.baselet.gwt.client.view.widgets.propertiespanel.PropertiesTextArea; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.resources.client.TextResource; import com.google.gwt.user.client.ui.ListBox; public class DrawPanelPalette extends DrawPanel { private static final List PALETTELIST = Arrays.asList( Resources.INSTANCE.UML_Common_Elements(), Resources.INSTANCE.Generic_Colors(), Resources.INSTANCE.Generic_Layers(), Resources.INSTANCE.Generic_Text_and_Alignment(), Resources.INSTANCE.UML_Activity(), Resources.INSTANCE.UML_Class(), Resources.INSTANCE.UML_Composite_Structure(), Resources.INSTANCE.UML_Package(), Resources.INSTANCE.UML_Sequence(), Resources.INSTANCE.UML_State_Machine(), Resources.INSTANCE.UML_Structure_and_Deployment(), Resources.INSTANCE.UML_Use_Case(), Resources.INSTANCE.Plots()); private final Map paletteCache = new HashMap<>(); private final ListBox paletteChooser; public DrawPanelPalette(MainView mainView, PropertiesTextArea propertiesPanel, final ListBox paletteChooser) { super(mainView, propertiesPanel); setDiagram(parsePalette(PALETTELIST.get(0))); this.paletteChooser = paletteChooser; for (TextResource r : PALETTELIST) { paletteChooser.addItem(r.getName().replaceAll("_", " ")); } paletteChooser.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { setDiagram(parsePalette(PALETTELIST.get(paletteChooser.getSelectedIndex()))); selector.deselectAll(); } }); paletteChooser.addMouseDownHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { event.stopPropagation(); // avoid propagation of mouseclick to palette which can be under the opened listbox } }); } private Diagram parsePalette(TextResource res) { Diagram diagram = paletteCache.get(res); if (diagram == null) { diagram = DiagramXmlParser.xmlToDiagram(res.getText()); paletteCache.put(res, diagram); } return diagram; } @Override public void onDoubleClick(GridElement ge) { if (ge != null && !propertiesPanel.getPaletteShouldIgnoreMouseClicks()) { otherDrawFocusPanel.setFocus(true); GridElement e = ElementFactoryGwt.create(ge, otherDrawFocusPanel.getDiagram()); e.setProperty(GroupFacet.KEY, null); commandInvoker.realignElementsToVisibleRect(otherDrawFocusPanel, Arrays.asList(e)); commandInvoker.addElements(otherDrawFocusPanel, Arrays.asList(e)); } } private final List draggedElements = new ArrayList(); @Override void onMouseDown(GridElement element, boolean isControlKeyDown) { super.onMouseDown(element, isControlKeyDown); for (GridElement original : selector.getSelectedElements()) { draggedElements.add(ElementFactoryGwt.create(original, getDiagram())); } } @Override public void onMouseDragEnd(GridElement gridElement, Point lastPoint) { if (lastPoint.getX() < 0) { // mouse moved from palette to diagram -> insert elements to diagram List elementsToMove = new ArrayList(); for (GridElement original : selector.getSelectedElements()) { GridElement copy = ElementFactoryGwt.create(original, otherDrawFocusPanel.getDiagram()); int verticalScrollbarDiff = otherDrawFocusPanel.scrollPanel.getVerticalScrollPosition() - scrollPanel.getVerticalScrollPosition(); int horizontalScrollbarDiff = otherDrawFocusPanel.scrollPanel.getHorizontalScrollPosition() - scrollPanel.getHorizontalScrollPosition(); copy.setLocationDifference(otherDrawFocusPanel.getVisibleBounds().width + horizontalScrollbarDiff, paletteChooser.getOffsetHeight() + verticalScrollbarDiff); copy.setRectangle(SharedUtils.realignToGrid(copy.getRectangle(), false)); // realign location to grid (width and height should not be changed) elementsToMove.add(copy); } Selector.replaceGroupsWithNewGroups(elementsToMove, otherDrawFocusPanel.getSelector()); commandInvoker.removeSelectedElements(this); commandInvoker.addElements(this, draggedElements); selector.deselectAll(); commandInvoker.addElements(otherDrawFocusPanel, elementsToMove); } draggedElements.clear(); super.onMouseDragEnd(gridElement, lastPoint); } @Override protected StickableMap getStickablesToMoveWhenElementsMove(GridElement draggedElement, List elements) { // Moves at the palette NEVER stick return StickableMap.EMPTY_MAP; } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/0000755000175000017500000000000012533641120025022 5ustar benben././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Composite Structure.uxfumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Composite Struc0000644000175000017500000000742312533641120030414 0ustar benben 8 UMLGeneric 16 16 160 80 symbol=component Component UMLGeneric 16 176 160 88 symbol=component Component UMLGeneric 16 384 160 48 symbol=component Component Relation 168 56 56 184 lt=[>]-[>] 10.0;10.0;50.0;10.0;50.0;210.0;10.0;210.0 Relation 80 88 24 104 lt=[^]-[v] 10.0;10.0;10.0;110.0 Relation 56 88 24 104 lt=[=]-[<] 10.0;10.0;10.0;110.0 Relation 24 88 40 104 lt=[GUI]-[SQL] 20.0;10.0;20.0;110.0 Relation 96 88 40 64 lt=[v]-( 20.0;10.0;20.0;50.0 Relation 104 136 24 56 lt=()-[v] 10.0;10.0;10.0;50.0 Relation 56 256 80 96 lt=[].> m2=<<delegate>> 60.0;10.0;10.0;60.0;10.0;100.0 Relation 56 336 24 64 lt=()- 10.0;10.0;10.0;60.0 Relation 104 264 104 88 lt=<. m2=<<delegate>> 10.0;10.0;40.0;50.0;40.0;90.0 Relation 120 336 40 64 lt=)- 20.0;20.0;20.0;60.0 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Use Case.uxf0000644000175000017500000001031312533641120027552 0ustar benben 8 UMLUseCase 8 176 128 72 Use Case -- extension points valign=top UMLUseCase 16 16 96 32 Use case 1 UMLNote 152 176 104 56 Note.. bg=blue UMLActor 120 16 48 80 Actor UMLGeneric 112 256 144 56 Alt. Use Case -- extension points symbol=usecase Relation 16 152 112 24 lt=->> 10.0;10.0;120.0;10.0 UMLGeneric 176 16 80 80 System halign=left UMLGeneric 152 120 104 32 Neighboursystem valign=center Relation 16 128 104 24 lt=.() 10.0;10.0;110.0;10.0 Relation 16 104 112 32 10.0;20.0;120.0;20.0 Relation 16 96 112 24 lt=.>> 10.0;10.0;120.0;10.0 Relation 16 72 112 32 lt=.> <<extends>> 10.0;20.0;120.0;20.0 Relation 16 48 112 32 lt=.> <<includes>> 10.0;20.0;120.0;20.0 UMLHierarchy 8 320 360 216 type=WorkProcess Workprocess1 Workprocess2 Workprocess3 Workprocess4 Workprocess5 UMLHierarchy 264 16 160 296 type=Actor Actor1 Actor2 Actor3 Actor4 Actor5 Actor6 ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML State Machine.uxfumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML State Machine.u0000644000175000017500000000671312533641120030242 0ustar benben 8 UMLSpecialState 56 16 16 16 type=initial UMLSpecialState 104 16 16 16 type=termination UMLSpecialState 32 16 16 16 type=flow_final UMLSpecialState 80 16 16 16 type=final UMLSpecialState 120 80 32 32 type=decision UMLState 24 80 72 32 state UMLState 24 120 144 88 complex state -- some more... -- valign=top UMLState 64 232 80 32 state UMLState 32 304 96 48 state with substates symbol=substate Relation 16 48 152 24 lt=-> 10.0;10.0;170.0;10.0 Relation 24 240 96 64 lt=-> self 100.0;30.0;100.0;60.0;10.0;60.0;10.0;10.0;50.0;10.0 UMLSpecialState 128 16 16 16 type=history_shallow UMLSpecialState 152 16 16 16 type=history_deep umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Resources.java0000644000175000017500000000230412533641120027636 0ustar benbenpackage com.baselet.gwt.client.view.palettes; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.TextResource; public interface Resources extends ClientBundle { Resources INSTANCE = GWT.create(Resources.class); @Source("UML Common Elements.uxf") TextResource UML_Common_Elements(); @Source("Generic Colors.uxf") TextResource Generic_Colors(); @Source("Generic Layers.uxf") TextResource Generic_Layers(); @Source("Generic Text and Alignment.uxf") TextResource Generic_Text_and_Alignment(); @Source("UML Activity.uxf") TextResource UML_Activity(); @Source("UML Class.uxf") TextResource UML_Class(); @Source("UML Composite Structure.uxf") TextResource UML_Composite_Structure(); @Source("UML Package.uxf") TextResource UML_Package(); @Source("UML Sequence.uxf") TextResource UML_Sequence(); @Source("UML State Machine.uxf") TextResource UML_State_Machine(); @Source("UML Structure and Deployment.uxf") TextResource UML_Structure_and_Deployment(); @Source("UML Use Case.uxf") TextResource UML_Use_Case(); @Source("Plots.uxf") TextResource Plots(); } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Class.uxf0000644000175000017500000001750612533641120027242 0ustar benben 8 UMLClass 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long {composite} _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 -- Resp2 UMLClass 16 16 80 24 SimpleClass UMLClass 104 16 80 24 /AbstractClass/ UMLClass 192 16 88 32 type=actclass ActiveClass UMLClass 192 64 88 32 lw=2 ActiveClass UMLClass 192 112 88 32 lt=. Class with dashed border UMLClass 160 208 128 56 template=0: Object TemplateClass -- UMLNote 160 272 112 56 Note.. UMLUseCase 168 336 96 32 lt=. Collaboration UMLClass 288 16 136 104 OuterClass {innerclass InnerClass innerclass} {innerclass InnerClass {innerclass InnerInnerClass -- field innerclass} innerclass} UMLInterface 288 120 64 80 Interface -- Operation1 Operation2 Relation 8 208 152 24 lt=<<- 10.0;10.0;170.0;10.0 Relation 8 224 152 24 lt=<<. 10.0;10.0;170.0;10.0 Relation 8 240 152 24 lt=<- 10.0;10.0;170.0;10.0 Relation 8 256 152 24 lt=<. 10.0;10.0;170.0;10.0 Relation 8 328 152 32 lt=<- m1=0..n 10.0;10.0;170.0;10.0 Relation 8 352 152 24 lt=<<<- 10.0;10.0;170.0;10.0 Relation 8 368 152 24 lt=<<<<- 10.0;10.0;170.0;10.0 Relation 16 384 144 40 lt=[key]-> m2=0..1 m1=0..n 20.0;20.0;160.0;20.0 UMLClass 160 416 48 16 Rose bg=red Relation 184 392 104 48 lt=<<- a rose is a rose 30.0;40.0;70.0;40.0;70.0;10.0;10.0;10.0;10.0;30.0 Relation 16 424 136 40 lt=)- m1=require 20.0;20.0;150.0;20.0 Relation 16 456 128 40 lt=-() m2=provide 10.0;20.0;140.0;20.0 Relation 304 200 88 128 lt=- m1=1 r1=professor m2=1..n r2=student teaches to v 10.0;10.0;10.0;140.0 Relation 304 328 88 120 lt=- m1=0..n m2=1 teaches to ^ 10.0;10.0;10.0;130.0 Relation 8 272 152 40 lt=- m1=0..n m2=0..1 teaches to > 10.0;20.0;170.0;20.0 Relation 8 296 152 40 lt=- m1=3 m2=1 < teaches to 10.0;20.0;170.0;20.0 ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Structure and Deployment.uxfumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Structure and D0000644000175000017500000000533312533641120030256 0ustar benben 8 UMLDeployment 16 16 88 40 Node UMLDeployment 16 72 200 64 <<execution environment>> Name UMLDeployment 128 16 88 40 <<device>> Name UMLDeployment 16 144 200 64 <<Deployment Descriptor>> Name UMLGeneric 136 216 88 64 symbol=artifact Artifact UMLGeneric 16 216 112 64 symbol=component Component UMLGeneric 16 288 112 32 <<component>> Name UMLGeneric 136 288 88 32 <<artifact>> Name UMLGeneric 72 352 88 40 <<artefact>> Name group=1 UMLDeployment 16 328 200 72 Deployment group=1 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Plots.uxf0000644000175000017500000001067212533641120026655 0ustar benben // Uncomment the following line to change the fontsize and font: fontsize=10 // fontfamily=SansSerif //possible: SansSerif,Serif,Monospaced ////////////////////////////////////////////////////////////////////////////////////////////// // Welcome to UMLet! // // Double-click on elements to add them to the diagram, or to copy them // Edit elements by modifying the text in this panel // Hold Ctrl to select multiple elements // Use Ctrl+mouse to select via lasso // // Use +/- or Ctrl+mouse wheel to zoom // Drag a whole relation at its central square icon // // Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) // Edit the files in the "palettes" directory to create your own element palettes // // Select "Custom Elements > New..." to create new element types ////////////////////////////////////////////////////////////////////////////////////////////// // This text will be stored with each diagram; use it for notes. 10 PlotGrid 30 230 500 350 // datasets can have optional names set (in this case "first_name") data first_name a b c d 1 3 1 6 data a b c 2 -4 4 // some settings are global, like the width of the grid grid.width=4 // variables which are on the same line as "plot" are only set for this plot plot type=pie colors=red,blue,yellow,#3c7a00 // A variable which is on it's own line is valid for every following plot type=line colors=blue plot plot plot type=scatter plot type=scatter // auto resets the variable to it's default value (in this case "bar") type=auto colors=auto plot // to use the highest/lowest value of all datasets, set value.min/max to all value.min=all value.max=all plot // you can set the data to plot by number plot data=#1 // ... or by name plot data=first_name // a custom min/max value sets a custom range of values for the axis value.min=-6 value.max=10 plot PlotGrid 550 240 500 390 // there are numerous axis configurations which are shown here data a b c -5 7 13 type=line axis.desc.show= axis.value.show= axis.value.list=relevant plot axis.desc.show=axis plot axis.value.show=axis plot axis.desc.show=axis,line plot axis.value.show=axis,line plot axis.desc.show=axis,line,marker plot axis.value.show=axis,line,marker plot axis.desc.show=axis,line,marker,text plot axis.value.show=axis,line,marker,text plot axis.value.list= plot axis.value.list=-8,-1,3.5,17 plot axis.value.list=-8,-1,3.5,17,relevant plot PlotGrid 670 20 190 150 data a b c x -16 5.5 18.3 y 3 5 1 z 5 9 -3 type=scatter axis.value.show=axis axis.desc.show=axis,marker,text plot PlotGrid 220 20 170 130 // single plots are easily created without using capabilities of a (plot)grid data a b c 3 7 13 plot type=bar PlotGrid 20 20 170 130 // single plots are easily created without using capabilities of a (plot)grid data a b c 3 7 13 plot type=pie PlotGrid 450 20 190 150 data a b c x -16 5.5 18.3 y 3 5 1 z 5 9 -3 type=line axis.value.show=axis axis.desc.show=axis,marker,text plot data=#1 data.invert=true ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Common Elements.uxfumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Common Elements0000644000175000017500000002137512533641120030360 0ustar benben 8 UMLClass 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 *-- Resp2* UMLClass 104 16 80 24 /AbstractClass/ UMLClass 16 240 168 56 _object: Class_ -- id: Long="36548" [waiting for message] UMLClass 288 56 48 16 Rose bg=red UMLUseCase 16 304 96 32 Use case 1 UMLUseCase 104 328 96 32 *Use case 3* UMLUseCase 16 376 96 32 Use case 2 bg=blue UMLUseCase 16 448 96 32 lt=. Collaboration fg=red bg=yellow UMLActor 136 408 48 80 Actor UMLNote 216 304 112 56 Note.. bg=blue UMLPackage 216 376 112 56 EmptyPackage -- bg=orange UMLPackage 216 448 112 56 Package 1 -- -Content 1 +Content 2 bg=gray fg=red UMLInterface 200 8 64 80 Interface -- Operation1 Operation2 UMLClass 16 16 80 24 SimpleClass Text 336 168 80 56 This is a text element to place text anywhere. Relation 192 96 152 24 lt=<<- 10.0;10.0;170.0;10.0 Relation 192 112 152 24 lt=<<. 10.0;10.0;170.0;10.0 Relation 192 128 152 24 lt=<- 10.0;10.0;170.0;10.0 Relation 192 144 152 24 lt=<. 10.0;10.0;170.0;10.0 Relation 192 152 152 40 lt=- m1=0..n m2=0..1 teaches to > 10.0;20.0;170.0;20.0 Relation 192 176 152 32 lt=<.> <<someStereotype>> 10.0;20.0;170.0;20.0 Relation 192 200 152 32 lt=<- m1=0..n 10.0;10.0;170.0;10.0 Relation 192 224 152 24 lt=<<<- 10.0;10.0;170.0;10.0 Relation 192 240 152 24 lt=<<<<- 10.0;10.0;170.0;10.0 Relation 192 264 152 32 lt=[Qualification]<- m2=1..5,6 40.0;10.0;170.0;10.0 Relation 64 192 80 64 lt=<. <<instanceOf>> 40.0;10.0;40.0;60.0 Relation 40 328 56 64 lt=<. <<include>> 30.0;10.0;30.0;60.0 Relation 88 352 64 48 lt=.> <<extends>> 50.0;10.0;20.0;40.0 Relation 56 400 24 64 lt=<<. 10.0;10.0;10.0;60.0 Relation 88 400 72 48 10.0;10.0;70.0;40.0 Relation 312 32 104 48 lt=<<- a rose is a rose 30.0;40.0;70.0;40.0;70.0;10.0;10.0;10.0;10.0;30.0 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Generic Colors.uxf0000644000175000017500000000750512533641120030353 0ustar benben 8 UMLUseCase 8 8 88 32 red bg=red UMLUseCase 8 48 88 32 green bg=green UMLUseCase 8 88 88 32 blue bg=blue UMLUseCase 8 128 88 32 yellow bg=yellow UMLUseCase 112 8 88 32 white bg=white UMLUseCase 112 168 88 32 black bg=black fg=white UMLUseCase 112 88 88 32 gray bg=gray UMLUseCase 112 48 88 32 light_gray bg=light_gray UMLUseCase 112 128 88 32 dark_gray bg=dark_gray UMLUseCase 8 168 88 32 orange bg=orange UMLUseCase 112 208 88 32 pink bg=pink UMLUseCase 8 208 88 32 magenta bg=magenta UMLUseCase 8 248 88 32 cyan bg=cyan UMLUseCase 112 248 88 32 #3c7a00 bg=#3c7a00 UMLUseCase 8 288 88 32 cyan opaque bg=cyan transparency=0 layer=1 ././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Generic Text and Alignment.uxfumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Generic Text and Al0000644000175000017500000001017512533641120030272 0ustar benben 8 UMLClass 16 16 88 96 halign=left Top left bla bla bla UMLClass 120 16 88 96 halign=center Top center bla bla bla UMLClass 224 16 88 96 halign=right Top right bla bla bla UMLClass 16 120 88 96 valign=center halign=left Middle left bla bla bla UMLClass 120 120 88 96 valign=center halign=center Middle center bla bla bla UMLClass 224 120 88 96 valign=center halign=right Middle right bla bla bla UMLClass 16 224 88 96 valign=bottom halign=left Bottom left bla bla bla UMLClass 120 224 88 96 valign=bottom halign=center Bottom center bla bla bla UMLClass 224 224 88 96 valign=bottom halign=right Bottom right bla bla bla UMLClass 16 336 296 104 This class has the setting *style=wordwrap* -- Write text and watch how the linebreak is added automatically at the expected position to fill the whole class. You can also resize the class and see that the text will always fit the border style=wordwrap UMLClass 16 456 296 64 This class has the setting *style=autoresize* -- Write text <here>, and see how the class grows/shrinks.... style=autoresize UMLClass 16 544 112 88 This class has the settings *valign=center* *fontsize=18* *lw=2.5* valign=center fontsize=18 lw=2.5 UMLUseCase 152 544 152 72 this usecase has *halign=left* -- The text is always within the usecase circle halign=LEFT umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Package.uxf0000644000175000017500000000647012533641120027526 0ustar benben 8 UMLPackage 16 80 80 56 Text UMLPackage 16 144 80 56 Name -- Text Text halign=left UMLPackage 152 16 80 56 Name -- Text Text bg=blue UMLPackage 16 16 80 56 Name UMLPackage 152 128 80 56 Name -- Text Text bg=green UMLPackage 40 232 80 56 group=1 UMLPackage 16 208 120 88 group=1 Relation 24 312 120 32 lt=.> <<access>> 10.0;20.0;130.0;20.0 Relation 24 336 120 32 lt=.> <<import>> 10.0;20.0;130.0;20.0 Relation 24 360 120 32 lt=.> <<merge>> 10.0;20.0;130.0;20.0 Relation 184 72 24 88 lt=(+)- 10.0;10.0;10.0;90.0 UMLHierarchy 152 200 136 192 type=Package root name name name name root name umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/Generic Layers.uxf0000644000175000017500000000334312533641120030345 0ustar benben 10 UMLPackage 30 30 280 260 EmptyPackage -- bg=orange UMLClass 60 80 140 150 SimpleClass bg=blue layer=2 UMLClass 110 110 170 150 Foreground via the "layer" command bg=green layer=3 UMLPackage 30 310 280 260 EmptyPackage -- bg=orange UMLClass 60 360 140 150 SimpleClass bg=blue layer=2 UMLClass 110 390 170 150 Background via the "layer" command bg=white layer=1 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Sequence.uxf0000644000175000017500000001632712533641120027745 0ustar benben 8 UMLFrame 16 184 144 56 interaction frame UMLFrame 184 160 184 80 optional UMLFrame 16 248 360 200 interaction frame -- with inner frames -- -- group=1 UMLFrame 48 304 312 40 interaction frame group=1 UMLFrame 48 368 312 72 interaction frame -- inner group=1 UMLSpecialState 136 88 16 16 type=termination UMLSpecialState 320 200 16 16 type=termination UMLGeneric 136 16 16 48 UMLGeneric 176 16 80 24 _:O1_ bg=orange UMLGeneric 288 16 80 24 _:O2_ bg=red UMLGeneric 208 64 16 80 bg=yellow UMLGeneric 320 80 16 48 bg=red UMLGeneric 16 16 80 24 _:Instance_ Relation 48 32 24 56 lt=. 10.0;10.0;10.0;50.0 Relation 16 88 112 24 lt=<- 10.0;10.0;120.0;10.0 Relation 16 112 112 24 lt=<<<<<- 10.0;10.0;120.0;10.0 Relation 16 128 112 32 lt=<- asyncMsg 10.0;20.0;120.0;20.0 Relation 16 152 112 32 lt=<<- syncMsg 10.0;20.0;120.0;20.0 Relation 208 32 24 48 lt=. 10.0;10.0;10.0;40.0 Relation 320 32 24 64 lt=. 10.0;10.0;10.0;60.0 Relation 216 64 120 32 lt=->> sync call 10.0;20.0;130.0;20.0 Relation 216 112 120 32 lt=<- async return 10.0;20.0;130.0;20.0 Relation 208 136 24 80 lt=. 10.0;10.0;10.0;80.0 Relation 208 216 24 32 lt=. 10.0;10.0;10.0;20.0 Relation 320 120 24 104 lt=. 10.0;10.0;10.0;110.0 Relation 216 192 128 32 lt=-> async return 10.0;20.0;140.0;20.0 UMLGeneric 208 200 16 24 bg=yellow umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/palettes/UML Activity.uxf0000644000175000017500000002357312533641120027772 0ustar benben 8 UMLState 208 80 80 32 study bg=red UMLSpecialState 64 80 16 16 type=initial UMLSpecialState 64 104 16 16 type=final UMLSpecialState 24 80 32 32 type=decision UMLState 16 192 80 32 receive signal type=receiver UMLState 16 248 80 32 send signal type=sender UMLTimer 24 296 64 56 time signal UMLObject 16 360 80 32 DataObject UMLSpecialState 240 40 16 16 type=initial UMLObject 112 16 248 456 System valign=top UMLState 16 24 80 32 state UMLSpecialState 232 136 32 32 bg=green type=decision UMLTimer 144 128 48 56 July 1st bg=black UMLState 216 256 80 32 call taxi bg=yellow type=sender UMLState 216 304 80 32 taxi arrived bg=yellow type=receiver UMLState 128 280 80 32 grab bags bg=blue UMLState 176 400 96 32 leave for airport bg=green UMLSpecialState 216 448 16 16 type=final UMLSyncBarHorizontal 24 56 64 16 lw=5 UMLSyncBarVertical 88 72 16 56 template=txt title=titletext bg=red UMLSyncBarHorizontal 184 208 80 16 {joinSpec= date is on or after July 1st and the exam is passed} UMLSyncBarHorizontal 192 368 64 16 lw=5 Text 112 192 88 72 {joinSpec=date is on or after July 1stand the exam is passed} style=wordwrap UMLSpecialState 32 128 16 16 type=flow_final UMLSpecialState 64 128 16 16 type=termination Relation 16 160 96 24 lt=<- 10.0;10.0;100.0;10.0 Relation 240 40 24 56 lt=<- 10.0;50.0;10.0;10.0 Relation 240 104 24 48 lt=<- 10.0;40.0;10.0;10.0 Relation 224 144 136 328 lt=<- m2=[exam missed] 10.0;390.0;150.0;390.0;150.0;10.0;50.0;10.0 Relation 160 136 56 96 lt=<- 50.0;100.0;50.0;10.0;10.0;10.0 Relation 160 208 64 88 lt=<- 10.0;90.0;10.0;60.0;60.0;60.0;60.0;10.0 Relation 232 208 40 64 lt=<- 30.0;60.0;30.0;40.0;10.0;40.0;10.0;10.0 Relation 160 304 64 88 lt=<- 60.0;90.0;60.0;50.0;10.0;50.0;10.0;10.0 Relation 232 328 40 64 lt=<- 10.0;60.0;10.0;20.0;30.0;20.0;30.0;10.0 Relation 216 368 24 48 lt=<- 10.0;40.0;10.0;10.0 Relation 216 424 24 40 lt=<- 10.0;30.0;10.0;10.0 Relation 208 160 88 72 lt=<- [exam passed] 50.0;70.0;50.0;10.0 umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/Helptext.txt0000644000175000017500000000057412533641120025545 0ustar benbenDouble-click on an element to add it to the diagram (or use drag&drop) uxf Files using the Menu or simply drag them into the diagram diagrams to Standalone-UMLet-compatible uxf or png diagrams to persistent browser storage Only new elements work in standalone and web umlet Please report bugs at http://code.google.com/p/umlet/ halign=centerumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/SelectorNew.java0000644000175000017500000000202212533641120026272 0ustar benbenpackage com.baselet.gwt.client.view; import java.util.ArrayList; import java.util.List; import com.baselet.element.Selector; import com.baselet.element.interfaces.GridElement; import com.baselet.element.interfaces.HasGridElements; public class SelectorNew extends Selector { private HasGridElements gridElementProvider; public SelectorNew(HasGridElements gridElementProvider) { this.gridElementProvider = gridElementProvider; } public void setGridElementProvider(HasGridElements gridElementProvider) { this.gridElementProvider = gridElementProvider; } private List selectedElements = new ArrayList(); public GridElement getSingleSelected() { if (selectedElements.size() == 1) { return selectedElements.get(0); } else { return null; } } @Override public List getSelectedElements() { return selectedElements; } @Override public List getAllElements() { return gridElementProvider.getGridElements(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/0000755000175000017500000000000012533641120024647 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/MyPopupPanel.java0000644000175000017500000000274312533641120030111 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.Widget; public class MyPopupPanel extends PopupPanel { public enum Type { POPUP, MENU } private String header; private Type type; public MyPopupPanel(boolean glassEnabled, Type type) { super(true); setGlassEnabled(glassEnabled); this.type = type; } public void setHeader(String header) { this.header = header; } @Override public void setWidget(Widget w) { switch (type) { case POPUP: addStyleName("centerPopup"); w.addStyleName("centerPopupContent"); break; case MENU: addStyleName("menuPopup"); break; } if (header == null) { super.setWidget(w); } else { FlowPanel fp = new FlowPanel(); fp.add(new HTML("
" + header + "
")); fp.add(w); super.setWidget(fp); } } /** * pressing ESC closes the dialogbox */ @Override protected void onPreviewNativeEvent(NativePreviewEvent event) { super.onPreviewNativeEvent(event); if (event.getTypeInt() == Event.ONKEYDOWN && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) { hide(); } } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/MenuPopup.java0000644000175000017500000000206012533641120027440 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import java.util.List; import com.baselet.control.basics.geom.Point; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.MenuItem; public class MenuPopup extends MyPopupPanel { public static abstract class MenuPopupItem { private String text; public MenuPopupItem(String text) { super(); this.text = text; } public String getText() { return text; } public abstract void execute(); } public MenuPopup(List items) { super(false, Type.MENU); MenuBar popupMenuBar = new MenuBar(true); for (final MenuPopupItem item : items) { popupMenuBar.addItem(new MenuItem(item.getText(), true, new ScheduledCommand() { @Override public void execute() { item.execute(); hide(); } })); } popupMenuBar.setVisible(true); add(popupMenuBar); } public void show(Point p) { setPopupPosition(p.x, p.y); show(); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/OwnTextArea.java0000644000175000017500000000236712533641120027723 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.TextArea; public class OwnTextArea extends TextArea { private InstantValueChangeHandler handler; public OwnTextArea() { super(); sinkEvents(Event.ONPASTE); addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { fireHandler(); } }); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if (DOM.eventGetType(event) == Event.ONPASTE) { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { fireHandler(); } }); } } public void setInstantValueChangeHandler(InstantValueChangeHandler handler) { this.handler = handler; } public static interface InstantValueChangeHandler { void onValueChange(String value); } public void fireHandler() { handler.onValueChange(getText()); } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/DownloadPopupPanel.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/DownloadPopupPanel.j0000644000175000017500000000150612533641120030577 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.SimplePanel; public class DownloadPopupPanel extends MyPopupPanel { public DownloadPopupPanel(String uxfUrl, String pngUrl) { super(true, Type.POPUP); setHeader("Export Diagram"); String html = "

\"Right click -> Save as\" on the following links

" + "

" + link(uxfUrl) + "Diagram File

" + "

" + link(pngUrl) + "Image File

"; SimplePanel panel = new SimplePanel(new HTML(html)); panel.addStyleName("exportPopup"); setWidget(panel); center(); } private String link(String uxfUrl) { return ""; // apostrophes in datauris must be escaped because it's the closing sign fore the href } }././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/ShortcutDialogBox.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/ShortcutDialogBox.ja0000644000175000017500000000510412533641120030567 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import com.baselet.gwt.client.keyboard.Shortcut; import com.baselet.gwt.client.keyboard.Shortcut.Category; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; public class ShortcutDialogBox extends MyPopupPanel { private static class TableBuilder { SafeHtmlBuilder builder = new SafeHtmlBuilder(); int i = 0; public TableBuilder() { builder.appendHtmlConstant(""); } public void append(Shortcut shortcut) { String color = i++ % 2 != 0 ? "white" : "#E5E4E2"; builder.appendHtmlConstant(""); } public HTML toHTML() { builder.appendHtmlConstant("
" + shortcut.getShortcut() + "" + shortcut.getDescription() + "
"); return new HTML(builder.toSafeHtml()); } } private static ShortcutDialogBox instance = new ShortcutDialogBox(); public static ShortcutDialogBox getInstance() { return instance; } public ShortcutDialogBox() { super(true, Type.POPUP); setHeader("Keyboard Shortcuts"); Shortcut[] values = Shortcut.values(); Map map = new HashMap(); for (Shortcut.Category c : Shortcut.Category.values()) { map.put(c, new TableBuilder()); } for (Shortcut shortcut : values) { map.get(shortcut.getCategory()).append(shortcut); } FlowPanel panel = new FlowPanel(); boolean first = true; for (Shortcut.Category c : Arrays.asList(Category.values())) { String additional = ""; if (!first) { additional = "padding-top:0.5em;margin-top:0.5em;border-top:1px solid;"; } String header = "
" + c.getHeader() + "
"; first = false; panel.add(new HTML(header)); panel.add(map.get(c).toHTML()); } setWidget(panel); } /** * pressing ESC closes the dialogbox */ @Override protected void onPreviewNativeEvent(NativePreviewEvent event) { super.onPreviewNativeEvent(event); if (event.getTypeInt() == Event.ONKEYDOWN && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) { hide(); } } }umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/SaveDialogBox.java0000644000175000017500000000460712533641120030210 0ustar benbenpackage com.baselet.gwt.client.view.widgets; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.TextBox; public class SaveDialogBox extends MyPopupPanel { public static interface Callback { void callback(String chosenName); } private final TextBox textBox = new TextBox(); private final Button saveButton = new Button("Save"); private final Button cancelButton = new Button("Cancel"); public SaveDialogBox(final Callback callback) { super(true, Type.POPUP); setHeader("Save Diagram"); textBox.addKeyPressHandler(new KeyPressHandler() { @Override public void onKeyPress(KeyPressEvent event) { if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { submitDialog(callback); } } }); saveButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { submitDialog(callback); } }); cancelButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { hide(); } }); FlowPanel panel = new FlowPanel(); panel.add(new HTML("Please choose a name")); panel.add(textBox); FlowPanel fp = new FlowPanel(); fp.add(saveButton); fp.add(cancelButton); panel.add(fp); setWidget(panel); } private void submitDialog(final Callback callback) { if (textBox.getText().isEmpty()) { Window.alert("You must enter a name to save the diagram"); } else { hide(); callback.callback(textBox.getText()); } } public void clearAndCenter() { center(); textBox.setFocus(true); } /** * pressing ESC closes the dialogbox */ @Override protected void onPreviewNativeEvent(NativePreviewEvent event) { super.onPreviewNativeEvent(event); if (event.getTypeInt() == Event.ONKEYDOWN && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) { hide(); } } }umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/0000755000175000017500000000000012533641120030063 5ustar benben././@LongLink0000644000000000000000000000017000000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/PropertiesTextArea.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/Prop0000644000175000017500000000350712533641120030733 0ustar benbenpackage com.baselet.gwt.client.view.widgets.propertiespanel; import com.baselet.element.interfaces.HasPanelAttributes; import com.baselet.gwt.client.view.interfaces.Redrawable; import com.baselet.gwt.client.view.widgets.OwnTextArea; import com.baselet.gwt.client.view.widgets.OwnTextArea.InstantValueChangeHandler; import com.google.gwt.uibinder.client.UiConstructor; public class PropertiesTextArea extends MySuggestBox { private static final String DEFAULT_HELPTEXT = "Space for diagram notes"; private final OwnTextArea textArea; private final MySuggestOracle oracle; private HasPanelAttributes gridElement; private Redrawable activePanel = null; @UiConstructor public PropertiesTextArea() { this(new MySuggestOracle(), new OwnTextArea()); textArea.setInstantValueChangeHandler(new InstantValueChangeHandler() { @Override public void onValueChange(String value) { if (gridElement != null) { gridElement.setPanelAttributes(getValue()); } activePanel.redraw(); } }); } public PropertiesTextArea(final MySuggestOracle oracle, OwnTextArea textArea) { super(oracle, textArea); this.oracle = oracle; this.textArea = textArea; } public void setGridElement(HasPanelAttributes panelAttributeProvider, Redrawable panel) { activePanel = panel; gridElement = panelAttributeProvider; String panelAttributes = panelAttributeProvider.getPanelAttributes(); if (panelAttributes == null) { panelAttributes = DEFAULT_HELPTEXT; } textArea.setValue(panelAttributes); oracle.setAutocompletionList(panelAttributeProvider.getAutocompletionList()); } /** * also fire texthandlers if a text is inserted via choosing a selectionbox entry */ @Override public void setText(String text) { super.setText(text); textArea.fireHandler(); } } ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySuggestBox.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySu0000644000175000017500000000706212533641120030710 0ustar benbenpackage com.baselet.gwt.client.view.widgets.propertiespanel; import com.baselet.gwt.client.keyboard.Shortcut; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.ValueBoxBase; public class MySuggestBox extends SuggestBox { private String lastRequestLine; private final MySuggestionDisplay display; public MySuggestBox(final MySuggestOracle oracle, ValueBoxBase textArea) { this(oracle, textArea, new MySuggestionDisplay()); } public MySuggestBox(final MySuggestOracle oracle, ValueBoxBase textArea, final MySuggestionDisplay display) { super(oracle, textArea, display); this.display = display; getValueBox().addMouseUpHandler(new MouseUpHandler() { @Override public void onMouseUp(MouseUpEvent event) { showSuggestionList(); // switching line of textarea by click should also update the shown suggestions } }); textArea.addKeyDownHandler(new KeyDownHandler() { // CTRL+Space shows all suggestions @Override public void onKeyDown(KeyDownEvent event) { int key = event.getNativeEvent().getKeyCode(); if (display.isSuggestionListShowing()) { if (key == KeyCodes.KEY_ESCAPE) { display.hideSuggestions(); } else if ((key == KeyCodes.KEY_ENTER || key == KeyCodes.KEY_UP || key == KeyCodes.KEY_DOWN) && oracle.getSuggestionsForText(lastRequestLine).size() > 1) { event.getNativeEvent().preventDefault(); // if the focus is on the suggestbox and it has >1 entries, avoid propagating keyevents to the textarea } } if (Shortcut.SHOW_AUTOCOMPLETION.matches(event)) { event.getNativeEvent().preventDefault(); oracle.setShowAllAsDefault(true); showSuggestionList(); oracle.setShowAllAsDefault(false); } } }); } @Override public void setText(String text) { super.setText(replaceTextOfCurrentLine(text)); setFocus(true); // after choosing one of the suggestions, refocus the textarea } @Override public String getText() { lastRequestLine = getCursorLine(); return lastRequestLine; } private String getCursorLine() { String returnText = ""; String wholeText = super.getText(); if (!wholeText.contains("\n")) { returnText = wholeText; } else { int cursorPos = getValueBox().getCursorPos(); int currentPos = 0; for (String line : wholeText.split("(\r)?\n")) { currentPos += line.length() + 1; if (cursorPos < currentPos) { returnText = line; break; } } } return returnText; } private String replaceTextOfCurrentLine(String newText) { StringBuilder sb = new StringBuilder(""); String wholeText = super.getText(); if (!wholeText.contains("\n")) { sb.append(newText); } else { boolean replaced = false; int cursorPos = getValueBox().getCursorPos(); int currentPos = 0; for (String line : wholeText.split("(\r)?\n", -1)) { currentPos += line.length() + 1; if (cursorPos < currentPos && !replaced) { sb.append(newText).append("\n"); replaced = true; } else { sb.append(line).append("\n"); } } sb.setLength(sb.length() - 1); } return sb.toString(); } public boolean getPaletteShouldIgnoreMouseClicks() { return display.getPaletteShouldIgnoreMouseClicks(); } } ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySuggestion.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySu0000644000175000017500000000112312533641120030700 0ustar benbenpackage com.baselet.gwt.client.view.widgets.propertiespanel; import com.baselet.gui.AutocompletionText; import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; public class MySuggestion implements Suggestion { private AutocompletionText autoCompletionText; public MySuggestion(AutocompletionText autoCompletionText) { this.autoCompletionText = autoCompletionText; } @Override public String getDisplayString() { return autoCompletionText.getHtmlInfo(); } @Override public String getReplacementString() { return autoCompletionText.getText(); } }././@LongLink0000644000000000000000000000016500000000000011605 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySuggestOracle.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySu0000644000175000017500000000431112533641120030702 0ustar benbenpackage com.baselet.gwt.client.view.widgets.propertiespanel; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import com.baselet.gui.AutocompletionText; import com.google.gwt.user.client.ui.SuggestOracle; public class MySuggestOracle extends SuggestOracle { @Override public boolean isDisplayStringHTML() { return true; } private List suggestions = new ArrayList(); @Override public void requestSuggestions(final Request request, final Callback callback) { Collection result = getSuggestionsForText(request.getQuery()); Response response = new Response(result); callback.onSuggestionsReady(request, response); } public Collection getSuggestionsForText(String userInput) { String userInputLc = userInput.toLowerCase(); Collection result = new LinkedList(); for (Suggestion suggestion : suggestions) { if (suggestion.getReplacementString().toLowerCase().startsWith(userInputLc)) { result.add(highlightUserInput(suggestion, userInputLc)); } } return result; } private Suggestion highlightUserInput(final Suggestion suggestion, final String userInput) { return new Suggestion() { @Override public String getReplacementString() { return suggestion.getReplacementString(); } @Override public String getDisplayString() { return "" + userInput + "" + suggestion.getDisplayString().substring(userInput.length()); } }; } public void setAutocompletionList(List autocompletionList) { suggestions.clear(); for (AutocompletionText text : autocompletionList) { suggestions.add(new MySuggestion(text)); } } private boolean showAllAsDefault = false; public void setShowAllAsDefault(boolean showAllAsDefault) { this.showAllAsDefault = showAllAsDefault; } @Override public void requestDefaultSuggestions(final Request request, final Callback callback) { if (showAllAsDefault) { callback.onSuggestionsReady(request, new Response(suggestions)); } else { super.requestDefaultSuggestions(request, callback); } } } ././@LongLink0000644000000000000000000000017100000000000011602 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySuggestionDisplay.javaumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/widgets/propertiespanel/MySu0000644000175000017500000000432012533641120030702 0ustar benbenpackage com.baselet.gwt.client.view.widgets.propertiespanel; import java.util.Collection; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay; import com.google.gwt.user.client.ui.SuggestBox.SuggestionCallback; import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; /** * The purpose of this class is to avoid mouse interaction with the palette as long as the suggestbox is visible * a clean approach would be avoiding event-propagation (eg: with event.stopPropagation()) but unfortunately * GWT DefaultSuggestionDisplay is very inflexible and it would be necessary to change the behavior of MenuBar.onBrowserEvent(Event event) * This is not possible without copying many classes because of package-private visibility * * This alternative approach uses a timer to avoid palette interaction for some time after the popup closes to make sure mouseevents can be avoided */ public class MySuggestionDisplay extends DefaultSuggestionDisplay { private boolean paletteShouldIgnoreMouseClicks = false; private Timer popupHideTimer = new Timer() { @Override public void run() { paletteShouldIgnoreMouseClicks = false; } }; @Override protected PopupPanel createPopup() { PopupPanel p = super.createPopup(); p.addCloseHandler(new CloseHandler() { @Override public void onClose(CloseEvent event) { popupHideTimer.schedule(400); } }); return p; } @Override protected void showSuggestions(SuggestBox suggestBox, Collection suggestions, boolean isDisplayStringHTML, boolean isAutoSelectEnabled, SuggestionCallback callback) { super.showSuggestions(suggestBox, suggestions, isDisplayStringHTML, isAutoSelectEnabled, callback); if (isSuggestionListShowing()) { popupHideTimer.cancel(); paletteShouldIgnoreMouseClicks = true; } } public boolean getPaletteShouldIgnoreMouseClicks() { return paletteShouldIgnoreMouseClicks; } };umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/view/MainView.java0000644000175000017500000002126312533641120025567 0ustar benbenpackage com.baselet.gwt.client.view; import org.apache.log4j.Logger; import org.vectomatic.file.FileUploadExt; import com.baselet.gwt.client.base.Notification; import com.baselet.gwt.client.element.BrowserStorage; import com.baselet.gwt.client.element.DiagramXmlParser; import com.baselet.gwt.client.view.panel.wrapper.AutoResizeScrollDropPanel; import com.baselet.gwt.client.view.panel.wrapper.FileOpenHandler; import com.baselet.gwt.client.view.widgets.DownloadPopupPanel; import com.baselet.gwt.client.view.widgets.SaveDialogBox; import com.baselet.gwt.client.view.widgets.SaveDialogBox.Callback; import com.baselet.gwt.client.view.widgets.ShortcutDialogBox; import com.baselet.gwt.client.view.widgets.propertiespanel.PropertiesTextArea; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.MouseWheelEvent; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.RootLayoutPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.SplitLayoutPanel; import com.google.gwt.user.client.ui.Widget; public class MainView extends Composite { private static MainViewUiBinder uiBinder = GWT.create(MainViewUiBinder.class); interface MainViewUiBinder extends UiBinder {} interface MyStyle extends CssResource { String menuItem(); } @UiField MyStyle style; @UiField FocusPanel mainPanel; @UiField(provided = true) SplitLayoutPanel diagramPaletteSplitter = new SplitLayoutPanel(4) { @Override public void onResize() { super.onResize(); updateNotificationPosition(); } }; @UiField FlowPanel menuPanel; @UiField FlowPanel restoreMenuPanel; @UiField(provided = true) SplitLayoutPanel palettePropertiesSplitter = new SplitLayoutPanel() { @Override public void onResize() { diagramPanel.redraw(); palettePanel.redraw(); }; }; @UiField DockLayoutPanel paletteChooserCanvasSplitter; @UiField SimpleLayoutPanel diagramPanelWrapper; @UiField ListBox paletteChooser; @UiField PropertiesTextArea propertiesPanel; @UiField SimpleLayoutPanel palettePanelWrapper; private DrawPanel diagramPanel; private AutoResizeScrollDropPanel diagramScrollPanel; private DrawPanel palettePanel; private AutoResizeScrollDropPanel paletteScrollPanel; private FileUploadExt hiddenUploadButton = new FileUploadExt(); private FileOpenHandler handler; private Logger log = Logger.getLogger(MainView.class); private ScheduledCommand saveCommand = new ScheduledCommand() { private SaveDialogBox saveDialogBox = new SaveDialogBox(new Callback() { @Override public void callback(final String chosenName) { boolean itemIsNewlyAdded = BrowserStorage.getSavedDiagram(chosenName) == null; BrowserStorage.addSavedDiagram(chosenName, DiagramXmlParser.diagramToXml(diagramPanel.getDiagram())); if (itemIsNewlyAdded) { addRestoreMenuItem(chosenName); } Notification.showInfo("Diagram saved as: " + chosenName); } }); @Override public void execute() { saveDialogBox.clearAndCenter(); } }; public ScheduledCommand getSaveCommand() { return saveCommand; } public MainView() { initWidget(uiBinder.createAndBindUi(this)); diagramPaletteSplitter.setWidgetToggleDisplayAllowed(palettePropertiesSplitter, true); diagramPaletteSplitter.setWidgetSnapClosedSize(palettePropertiesSplitter, 100); diagramPaletteSplitter.setWidgetMinSize(palettePropertiesSplitter, 200); diagramPaletteSplitter.setWidgetToggleDisplayAllowed(menuPanel, true); diagramPaletteSplitter.setWidgetSnapClosedSize(menuPanel, 25); diagramPaletteSplitter.setWidgetMinSize(menuPanel, 50); palettePropertiesSplitter.setWidgetToggleDisplayAllowed(paletteChooserCanvasSplitter, true); diagramPanel = new DrawPanelDiagram(this, propertiesPanel); palettePanel = new DrawPanelPalette(this, propertiesPanel, paletteChooser); diagramPanel.setOtherDrawFocusPanel(palettePanel); palettePanel.setOtherDrawFocusPanel(diagramPanel); diagramScrollPanel = new AutoResizeScrollDropPanel(diagramPanel); paletteScrollPanel = new AutoResizeScrollDropPanel(palettePanel); updateNotificationPosition(); for (String diagramName : BrowserStorage.getSavedDiagramKeys()) { addRestoreMenuItem(diagramName); } log.trace("Main View initialized"); handler = new FileOpenHandler(diagramPanel); diagramPanelWrapper.add(diagramScrollPanel); palettePanelWrapper.add(paletteScrollPanel); RootLayoutPanel.get().add(hiddenUploadButton); hiddenUploadButton.setVisible(false); hiddenUploadButton.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { handler.processFiles(hiddenUploadButton.getFiles()); } }); EventHandlingUtils.addEventHandler(mainPanel, diagramPanel, palettePanel); } private void addRestoreMenuItem(final String chosenName) { final HorizontalPanel hp = new HorizontalPanel(); Label label = new Label(chosenName); label.setTitle("open diagram " + chosenName); label.addStyleName(style.menuItem()); label.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { diagramPanel.setDiagram(DiagramXmlParser.xmlToDiagram(BrowserStorage.getSavedDiagram(chosenName))); Notification.showInfo("Diagram opened: " + chosenName); } }); Image img = new Image("data:image/gif;base64,R0lGODlhCgAKAJEAAAAAAP////8AAP///yH5BAEAAAMALAAAAAAKAAoAAAIUnI8jgmvLlHtwnpqkpZh72UTZUQAAOw=="); img.setTitle("delete diagram " + chosenName); img.addStyleName(style.menuItem()); img.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (Window.confirm("Delete saved diagram " + chosenName)) { BrowserStorage.removeSavedDiagram(chosenName); restoreMenuPanel.remove(hp); Notification.showInfo("Deleted diagram: " + chosenName); } } }); hp.add(img); hp.add(label); restoreMenuPanel.add(hp); } @UiHandler("importMenuItem") void onImportMenuItemClick(ClickEvent event) { hiddenUploadButton.click(); } @UiHandler("exportMenuItem") void onExportMenuItemClick(ClickEvent event) { log.info("Exporting: " + DiagramXmlParser.diagramToXml(true, diagramPanel.getDiagram())); String uxfUrl = "data:text/xml;charset=utf-8," + DiagramXmlParser.diagramToXml(true, diagramPanel.getDiagram()); String pngUrl = CanvasUtils.createPngCanvasDataUrl(diagramPanel.getDiagram()); new DownloadPopupPanel(uxfUrl, pngUrl); } @UiHandler("saveMenuItem") void onSaveMenuItemClick(ClickEvent event) { saveCommand.execute(); } @UiHandler("helpMenuItem") void onHelpMenuItemClick(ClickEvent event) { ShortcutDialogBox.getInstance().center(); } @UiHandler("paletteChooser") void onPaletteChooserMouseWheel(MouseWheelEvent event) { // determine new index based on scroll direction int newIndex = paletteChooser.getSelectedIndex(); if (event.getDeltaY() < 0) { newIndex--; } else { newIndex++; } // set new index (if it's valid) and trigger change event (is not automatically triggered) if (newIndex >= 0 && newIndex < paletteChooser.getItemCount()) { paletteChooser.setSelectedIndex(newIndex); DomEvent.fireNativeEvent(Document.get().createChangeEvent(), paletteChooser); } } private void updateNotificationPosition() { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { RootPanel.get("featurewarning").getElement().getStyle().setMarginLeft(menuPanel.getOffsetWidth(), Unit.PX); } }); } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/keyboard/0000755000175000017500000000000012533641120024027 5ustar benbenumlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/keyboard/Shortcut.java0000644000175000017500000001271212533641120026510 0ustar benbenpackage com.baselet.gwt.client.keyboard; import com.google.gwt.event.dom.client.KeyCodeEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.shared.EventHandler; public enum Shortcut { // DIAGRAM SHORTCUTS DELETE_ELEMENT("DELETE BACKSPACE", "delete the currently selected elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_DELETE || code == KeyCodes.KEY_BACKSPACE; } }), SELECT_ALL("Ctrl+A", "select all elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'A'; } }), DESELECT_ALL("Ctrl+Shift+A Ctrl+D", "deselect all elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'D' || event.isControlKeyDown() && event.isShiftKeyDown() && code == 'A'; } }), COPY("Ctrl+C", "copy selected elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'C'; } }), CUT("Ctrl+X", "cut selected elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'X'; } }), PASTE("Ctrl+V", "paste cut or copied elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'V'; } }), SAVE("Ctrl+S", "save current diagram in browser storage", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && code == 'S'; } }), DISABLE_STICKING("SHIFT", "hold to disable sticking of elements", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_SHIFT; } }), MOVE_UP("Cursor ↑", "moves selected element(s) up", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_UP; } }), MOVE_DOWN("Cursor ↓", "moves selected element(s) down", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_DOWN; } }), MOVE_LEFT("Cursor â†", "moves selected element(s) left", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_LEFT; } }), MOVE_RIGHT("Cursor →", "moves selected element(s) right", Category.DIAGRAM, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return code == KeyCodes.KEY_RIGHT; } }), // BROWSER SHORTCUTS FULLSCREEN("F11", "switch to fullscreen", Category.BROWSER, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return KeyCodesExt.isSwitchToFullscreen(code); } }), ZOOM_IN("Ctrl+PLUS", "zoom diagram in", Category.BROWSER, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && KeyCodesExt.isPlus(code); } }), ZOOM_OUT("Ctrl+MINUS", "zoom diagram out", Category.BROWSER, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && KeyCodesExt.isMinus(code); } }), ZOOM_RESET("Ctrl+0", "reset diagram zoom", Category.BROWSER, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && KeyCodesExt.isZero(code); } }), // PROPERTIES PANEL SHORTCUTS SHOW_AUTOCOMPLETION("Ctrl+SPACE", "Show all autocompletion suggestions", Category.PROPERTIES, new Check() { @Override public boolean check(int code, KeyCodeEvent event) { return event.isControlKeyDown() && KeyCodesExt.isSpace(code); } }), ; private static interface Check { public boolean check(int code, KeyCodeEvent event); } public enum Category { DIAGRAM("DIAGRAM"), BROWSER("BROWSER (only if browser supports them)"), PROPERTIES("PROPERTIES PANEL"); private String header; private Category(String header) { this.header = header; } public String getHeader() { return header; } } private String shortcut; private String description; private Category category; private Check check; Shortcut(String shortcut, String description, Category category, Check check) { this.shortcut = shortcut; this.description = description; this.category = category; this.check = check; } public boolean matches(KeyCodeEvent event) { return check.check(event.getNativeKeyCode(), event); } public String getShortcut() { return shortcut; } public String getDescription() { return description; } public Category getCategory() { return category; } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/keyboard/KeyCodesExt.java0000644000175000017500000000127412533641120027065 0ustar benbenpackage com.baselet.gwt.client.keyboard; /** * helper class to detect keycodes * see http://www.javascripter.net/faq/keycodes.htm (not up to date because it doesnt list 171 as +) * and http://www.w3.org/2002/09/tests/keys.html */ class KeyCodesExt { static boolean isPlus(int code) { return code == 61 || code == 187 || code == 107 || code == 171; } static boolean isMinus(int code) { return code == 109 || code == 173 || code == 189; } static boolean isZero(int code) { return code == 48 || code == 96; } static boolean isSpace(int code) { return code == 32; } static boolean isSwitchToFullscreen(int code) { return code == 122; // F11 } } umlet-2015-06-03_UMLet_v13.3/BaseletGWT/src/com/baselet/gwt/client/BaseletGWT.java0000644000175000017500000000520212533641120025032 0ustar benbenpackage com.baselet.gwt.client; import org.apache.log4j.Logger; import com.baselet.control.config.SharedConfig; import com.baselet.gwt.client.base.Browser; import com.baselet.gwt.client.base.Notification; import com.baselet.gwt.client.element.BrowserStorage; import com.baselet.gwt.client.view.MainView; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.RunAsyncCallback; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.Location; import com.google.gwt.user.client.ui.RootLayoutPanel; public class BaseletGWT implements EntryPoint { Logger log = Logger.getLogger(BaseletGWT.class); @Override public void onModuleLoad() { SharedConfig.getInstance().setDev_mode(Location.getParameter("dev") != null); if (!BrowserStorage.initLocalStorageAndCheckIfAvailable()) { if (Browser.get() == Browser.INTERNET_EXPLORER && GWT.getHostPageBaseURL().startsWith("file:")) { Notification.showFeatureNotSupported("You have opened this webpage from your filesystem, therefore
Internet Explorer will not support local storage

Please use another browser like Firefox or Chrome,
or open this application using the web url", false); } else { Notification.showFeatureNotSupported("Sorry, but your browser does not support the required HTML 5 feature 'local storage' (or has cookies disabled)
Suggested browsers are Firefox, Chrome, Opera, Internet Explorer 10+", false); } } else if (!browserSupportsFileReader()) { Notification.showFeatureNotSupported("Sorry, but your browser does not support the required HTML 5 feature 'file reader'
Suggested browsers are Firefox, Chrome, Opera, Internet Explorer 10+", false); } else { Notification.showInfo("Loading application ... please wait ..."); GWT.runAsync(new RunAsyncCallback() { @Override public void onSuccess() { Notification.showInfo(""); RootLayoutPanel.get().add(new MainView()); } @Override public void onFailure(Throwable reason) { Notification.showFeatureNotSupported("Cannot load application from server", false); } }); if (!SharedConfig.getInstance().isDev_mode()) { Window.addWindowClosingHandler(new Window.ClosingHandler() { @Override public void onWindowClosing(Window.ClosingEvent closingEvent) { closingEvent.setMessage("Do you really want to leave the page? You will lose any unsaved changes."); } }); } } } private final native boolean browserSupportsFileReader() /*-{ return typeof FileReader != "undefined"; }-*/; } umlet-2015-06-03_UMLet_v13.3/Baselet/0000755000175000017500000000000012533641120014602 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/img/0000755000175000017500000000000012533641120015356 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo40.png0000644000175000017500000000277712533641120020413 0ustar benben‰PNG  IHDR((ûùˆûbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ )¨Êå:ŒIDATXÃíXMlTUþî}¿óÞt†é;ÖòS¦¥?©1!teD#&,ÑÓD–"&mb”…ãÎEG‰$ÄD@" EA\XhBb•©€µ”Ú™)ôçuÚéü¾w\̼áÍtÚN Ä`z’“¼¹÷žïž{îù»,F@@ @'~!Q\€ÎÜ*®²%"^ï¹¢xTÓßøjsGí¢{`\U8!D.Œõ¶X©ºiQ uæ†),nR§ò †ÇCX1ÝöxŽ;!/‚ó¶,Äiê Ý¥öö»f!À*pÛ¥9'§ÿcbέ”Å‘Jç&%DÑpŒ«ˆÈÅX¯L9¥ÙŒì ëCNŒŽÜHwX\X<‰ûv¤ О=ƒÄH’ÂtâD’‹¸0n”ذ’OÚßÜþHHY`”eŒÌ‚±Ãkê”Í0©ë¿þí¯½€Ç‡î)JWÜïON+2 y½—Î7Õ.dV-Û-€2œSJàd2FÎñ›~¿¼$˜½8!ŠTͺ¨Çs®Òt1€|µc…ï}wþiÚ½ûV>Ø k6·Î`ÑÉ/âä”å¸Á@’ëÝÊ*ÏÒÈ~€!¬m<MóÑâ/å»ÁÀ%¡)D p>“œ§ë ×{Ü>NRŒòùkuþ =ï ’%)æÒŽãJ.‰qÂ*ýOèbkû¦!¿ÿò´,S¼¦f8¢iVôÑöíj¶,nóœ‹êÚ×Uƒ}ÛÜ$;AL€R\¤Œ£|Y%$1Y Sè:ÿöòù„(&,€LӴË‚E5ý¨Éò`Ÿ=×),´.%sùÐcó"†q1¶ÄZÁí¹án€È÷•"Œ°VCÇÚøÈN€ðà?gîÛƒ•«ï`ýX’¾|êë3 HÒ¶mQ:u*FQ Á À"A˜!E™,¬–¤¯’rfÓŽIÌÌ%64Š›Áµk.ôôÄæ¥³â‘%¹@­°Ãêæ˜–…Ÿ¥æPž€€Ö½cÝÈï;‰®ó'ÎÆ˜~²™gzJDFuõ¨}ÃW6l ,x)¢hçCZ–Ûô¯W¸á„íàcšëã%¿ln•Ë#$Í9eÎÎ@3’”¬:ZÞygIèÙ¾i3¢iÇVÓ§[Z|w|kNž2$ùâ¨ÛýöjÊ\¥UªŠ=Þ-w5וçTxÜÌ+öxZàÓ´¾p­ë#UêûÆõ¢¡()ª,ªa“å{IC–“7Ö¸¥‡ªÜ¤¢TÜ4Ë8²<0àó@Š’y`Å®®o¬Éqn•ƒO)JæùÝ/ŠËÁŠËòT9NŠsú©icpEʶÉrB”Èd¼È 6<¹o¥ºr68™L ¸âª¦ó/mCJ˜eó ‹õþ‹IuM#À"Qš%Q˜#À"ÆÓÄxv+Á´ˆóÂß̬¸¯ýŒçK©^뛀Ï@¸pAÆ·†ðλÃhk⽃·ðêkù6§­Í@ ~ÖѸúûDéOœÿaœ§b8~, «Æø´°a’®G驯q¤Ù☬ĉ± ¹\SÄ…‰R‚".¤È펑®‘ ¤Šn\gªy"U3Èë+d£2 Ã".L‹ª<ò´GNHRáé~Ÿo®õ¯ØoÕ×jû²ÍÓªkå¯Ï«Á ;ǘ™:^Ì}Ó²œ~ó…W–Å3¢4UþÎI œ.nn >pº™PÕŠ¹,ÇMËò_CþÚÏ/ïÚµË^ßßÕµ7¢»÷N©j$·@¼§ª™‡š¬Ïƒâ¤£’TªUŒY“Š’ð{¥GZöÂ~ß–qUý&)ˆKÖ┠Шîî믯ߊUZ¥Çþ#à‚Ã>IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo24.png0000644000175000017500000000217412533641120020741 0ustar benben‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ &7„ƒÄ¬ IDATHÇ­UÝoTE=s»w?¹ÝÝîn[–¢VZ¨FjH-Ö`0?/´€Œ ðš 1Ñjô1õ’ªQ‰%« mlAù¦Ë’.÷înïîýÞãCK"¥PO2¿ÌÌ9™ß93Ü=;Ö5-JÒŸ%å>Rš }.é7*åZíû£ ‹T\Ò™ô$%•”m2X¹šéããAÌ‚¸µÐÞë9*çr^<>\ÅMz^AHR- …¿X|‚ªºX44\´å,Å@µª !ê¤R1æËç·—>ôk|ß¾wð_ÐOœè©( =€N$B7‘ [_O'‘˜ªz]!è( drj¾.A'¢°Ü”¶'ÿ°ñr’©Âºçǰº€áÉ~–¶ní'y{«J‡n7£ŠS]¨@£cµQü´·ù·¤<öÝ/k­Ýû}pÌ€s® kžp |þu=öñáÖWú¾h‡Äm®‹é¢Êé4€¼%bVJ¸®ƒ÷mo#€~ðü©hX±ÒFW—…ÓgjÐÐh*00À²å::t¨ªŒñ1-­E$S~LLT1v%„ÁÁZ ɤ|>ŒŠ™_}CPºv- †…‚Àªv™Œ‡ÎN¿l#ððÆ6 ƒƒa„Ã2º·˜8w¾Šg»‚°,@&£cçÎ2R©"z{DÂJ…ÈŒÉ>M«Â4 U•±r…ÇÕ`xH@+ºè\S†¦Zøû| ~Ù‚_®ÁéÑ(.]–pr ɤƒ½{r×Êxéå ²WÊ•&õ›VIÉ”„`È,«`dÄÆ‘#ÄbU<ÝQA{»ŽtSo¾•ÃæÍeŒŽ†ñXÆÄ¢ˆ‡ÆF<ìâ·ß=œ;ëàÔ©*l e±¨wÓ”þ¯Ô%ÝÝ:ëê 67ë<¦—T¸|ù$Óé2“mmeÖ×— xLÕ›lZª33ÙüèÔ|ëŠ2…pXWg0°ØÓ“žÈfÕÔŽ…ë€Ë©¼,tX<Ð[úr¦E‹Ç‹Ñ(¿ ‡çNø|ÑÔäB‰Hý3B{Ý:éXmÔõNO´´ÀVjÝ¡ÙoQ²{‹š›ºFÞž@Àåž=ê×w¼EËE>¸™NŒRÉxõ®<Ы©©±ˆ<2Ø×§}3g]‡™íoó€s_B2¹ñ,ÉE÷´);n½øÂú|ðæG.¾»KûçÂEkéü³Àê¶×_›¸ŽX¼»ÇxÜäî]ùó$Ÿš7ù•+–˜NV[ï'Úá tJ¢2-D.¥ÂM›&ÍC‡ÔÏH.¹×2ÇIüég½Í±åýh®&ž[+°æ™Ð籨÷ѪöÐ!„÷¿ÜP’Òéºß}ÿUO÷‰oZyIEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo48.png0000644000175000017500000000372512533641120020415 0ustar benben‰PNG  IHDR00 ÉbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ )#Á bIDAThÞíYmŒ”Õ~Î}gæý˜ý‚¥ [!ƢĴ²4˜¨hiÅR¨©­¦ÅÐJÛ4Z HõGú¯‰­i#?0‘"ÖDýÐ5MS“& í¶²*,°ììÎ,³ìÌî̼sŸþxgfggg?Æ]šîInæÍ½÷=ç¼çÜsÎsî3!7±mÛcêb$¼\%¥‹š‘H`7[[?% Çsâ±Ñå쪧Q¥˜ôùÆM–ò-y֢ܸ.9þtçÀ˜V…]Ÿ,X¸Ã5[­¦¢3Юj€9ñ~Ë ! ’%(ù™ *Q@ÅñKíÍK^a³\~«âTæöÔ¢:edð?F=¡Ð‡ +Âöúú­åëRé°lA•í+üJ§Uì:§Ç$HÖsYÞØ"Vp¨R‰ 4@x~ß("5ýظ©uuƒ ñÑG! ¼=„ÒãDù&U¬èéhÐyVCq ˆæ\N…ÝÁà GBOb„yš%Å-sœ‘KÓB!&ÓÆÈJ½¶ól)ã~3p±|Ï?êvEŠB]‘™ joúÒ+…Ã6ä3¦}éèòÛÂþ)R‘féxñÅ!dmm”‘È5n:Îþ(κº8`7Íúú·në'@¾öZq¾0”ߞϪ#,D¸QR•CN@…I’b’ðA“†–ÂvB‰¾å¹Ç¿g°Ä‰WB¡=S™(W⇫áðŸgìè~Ól/Ó\~è cVÇ5fÛ5 æòŽtExÝïhklÜ:ÌótPG]Í–”ÏH¸âQ 0­ã¶õö¬ÿbýF)­' ¬bô†‚‡ªf~¾¶Æ¯=1’s%Øl,›ŸW% ôeWÏ.hØ\XûkK‹À@ ÐVºïr(¼{fè+èsPÚ˜º\ ‡÷UtIñ8yÏ=‹§ÛŸ2Ôy?W#‘“à Hvû‹R‚Ó­“‡þáÂþ®ºÚ“3©^§Çšœ©AÕÕ`pß*›ãMøyMÝæò=×ýþ¶1„'쌄vÏX@{}½ŸÅT¡&-ú…|t­ÚT?{äZ“&»bЇ_Ÿ]º®´ûý W„ÌÁ¨a0f;oϳyš§ÿ ’¹fxfí×ZpùÒºFÓ|&‹[P€ EþͦŒ´¬þx݇gÎÜ4_vá‚Ök¦Õé*UĬ3˜aÌvú¯FB+þ«JoøÖ£êše}Pze1þú¢ú‘˜0ͳÐgÙrCß¹qƒÕkÛ¹©¬ª¦™ü¤¡á`o$rÔvÖ÷8öúÿöüâÅ'âŽÅŒLí­>Ël›såß[qÇIŸ¯L˜‡\¥Ø ﬖç¥pøÕ¬’ŠL+•먫kå»gQF©d%A}–ùòlùGmçPN&vK)Ÿ'¿z÷ªe!å¿ØÈR4Kîlµ^œú¥qàð—s±•ã^¡F¶y ~~y÷ ŸÿrDWyÇ"c tNñ× ‡ŽÔ&zn%Æd ~_¸ë%<¹%©n9Ÿ vf2«c ú\ùeZùxàAä-)Z–wÙfZÃÜ EÈP~ï¡m% ~ÿ׬MM¸dóÂF—\òyÏ † d8>ʈoŸ¤­©L÷®s ¾r[–éµ9f îè¿°wo/”î==¸ž:ÛñÚ"`+[t™ rxÿ”†Ï÷w„"Ã3?Ì7uÄãÛ®C¤£Ú“8ÈHmœï¼ëò؉þê…AŠJ ç:¿³õ E4Èßþ.I ;#¬3M"² èü4‘vS/¿?Üìö­,m‰I"»t¾áÇ+L볈÷Ï”*¾çñ(°Wæ¼ûTÀÍ‘¿©çpCƒ§×}}Õœ¤ÒwWßÝ2ìóW,<®{m»ê:uœWÝ éÓ«â^G–Íi1{úÁ‡­Ç™´ë<¾I8/ÔÔ¼Þu×êçc†ïÞ˜m¯¿²fÍKŸE"o$L“…æ±"ã–ÝvC±Ð’'žPqÛþ W5æ‘ɱû,ë¬÷oÎ ÂB•¨­©©µÇ¶:3ÕÓ):*F`¼å¦j0NÝ·©ù/‹íímn>Öݸ0]Ø8]ØxðãÅM{qô¨Â<ÍÓ<Í)ý€Äa’×i¼IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo64.png0000644000175000017500000000727012533641120020747 0ustar benben‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ';”.¹ÆEIDATxÚíZil\×uþÎ{³p8$Å”(J–%jµ"Y’µYJl¥m\ÉZYu-]À…Ñ:6 ¸iíáÆ±ã¶S´1¶€ÂA ZŽ NªÖ©­h·6JII¦H‘”È’³qÞ̼å~ý1Cr†»6› |ƒwùxß¹÷ìËàËñå˜ÐHz]L%w¾òܳîÛÏìhßMÅ´Ì,¿8c­­»©œì ÉD¿™ðB¶·±çä)”ݳ˜9]¡ ýþ]ù#VÂ@W0#e†ººƒ]AqAᴢ‚¥Å%,ÈóB**–¶«?«¬(«ÉO&aœ¿Àä¾}"óë0ík@»{zŒ8¼šû;‚V4ŠîPIÛâÕöŽM×5¯Ë媪¨œ_TàWÅ~?¤²\]im¾¼¢|U! óbzΊé=ö¨øý{oØÓÍÆuëPÖÒ Ã¶áª¬DéêÕ°W¯—,…{z<EÐ}>ÀëtH¦@3+nÀ ‡Á+-Ђqô0¢M(àÓ DDŽßê5«aÝ¿X¾®ªjx ýiœn/àqɲa%â0C½pZ[ ò ì£GÐ{þ<ò,šÇ⽿„wýZŸL+IÞ2lè±ß~«-þÔÓR’J”l˜º[4˜T° 8$ÔbB p à7܊Щ ÌÝG‰ÀÖ–h0E`°É N‚44t¸5ÀÃAœ.*€¨/(ÀòÖ«ÒR¹%›bg›Æ@€Ÿúòh‹FÜPdØ;'c}çLîyœ§taü™¿!£¡·Æ€drCòÉï1ævI #=ôƒ3"SƆ#`³/lmá-1@]i᥼<:Ðîqwlv|{;iÄWÞœô-gMò{O±ÏåšrÄ÷kÈ%Ÿlk»9-` À ϸê6Y‰§MM˜úñˤm/¿1â‰ñ·Þb¯Ç3¥?è3ðØ´"2¼1-°cQ¶×Õ1¥iS–ýr¹h?ÁT4¶n$Zµ“ƒk×À+Íð(É$ “dÄ÷Ŷ¾û<ùù®‘hö’©ÔÃÑS'aý韡‹À©Q«(QÐ8’<.{\¸ßJíP=n& vŸ(É+[¥Û$^2󱞟çí ‚\õÏuù€¸EÆÔ€mÊÏ/[åòï‡îš›¡]Ã`‚ „ Á“½/Ç8óX6¨ÆŒ ‘ŨZ0n¦9óÚ•h»šX[;ËwtTx¼ÅU-­&€epìÚôv¢ÒOfŽ!’KŒAÝXê!éÄÝ S]fPÞšj9Yó_îmÄ“µ°lT'Øp¡^V­Xœ8w. /ë,Z†øÌ8D¦Jp?¨¬ùH¼á ’QÞó&8z´<£šÀ¢Å_a(xïøQ7@ÂåêÅŒA@b ÓˆúbB¡r@jQ^ÞŸ¯"6,k:; @5m€al½÷æ¡°HG ËBc£È€M ¡¦¦ s¸ZIÂa¦Ç`[>\¿6€"Zú<£jŸ 3<ðÐÂÞ1ÕÊQ| BˆAÀaEe;I2a–IZ6©yü8éõžçž=¤i‘qƒì’À5*$ÐÆmÛ:ØÞA’¤í¤Ÿõõä²å1˜—©de‘†‘~ZvzíSO+’ä•èÈÂïP„„8é¿…™÷6=îz½‘!gù_†#;¦‘ä‚Ф8Ôô––}@Ó"7mú ýþ¹ôžß2Tü§Wz<'ùƒ4²§‡t{> h±¬Mû¸åá’äÞ½I.Xø ?âú gx¶žL$ÈÚ™'Xà?É„A—¼ÇÒ²wH’‹í£¦ÿ'Ãa‡ ~Âom?Í–Vh&àd• Š"¤Ëu•W®…EMïÓÏc!“‚€@9ŰÌ Ó^ÃØ€sç×áÀ§ðÈ#l§¶SÛ{&¨ TP×®àÍŸÎÆáÃ&¶n­GSãJôžŠÃ‡–`åʃ0Àþ÷WÁQQˆ$Ͱ¬e35ÊY Ñ4P•²K†hzsînÄîÝWñÇ^E~A ¥ Z›6QU<ðµnäûYßøÐgŒ“ Ú6‹:ƒf"`ƒÐŽƒŒh¼y.DB•žvvȧ·|…3g¯½Ö‘û"u8Î"¼þšùu`á…ç#°m?@•eBÅøÑ‹Qôôø²œ¯èöm}hþl!ž~z^yyZ[afM;Ü®(þå_WÀL?yc=ÊÊ­$“ãd‚¦ Ø6‡8°í16ØX·nî]üÞ×Û@”´FôÞ……iÞ^¸9'%}8r¤ Šs Z!~øbDx:³p•㥗\€¸!ìÍ|o£º&Š={jñÄçðæ›] ¼óóûpèàݘ3ï2æ×ý†ñ-,^ò.’‰‡²ðya™ã0À²†DOjé°OàþõeG€H(އ~¿zú±2©hú“êêNÜu— ë0uuå¸pY¡ÍIJeUÐPN^&Þd‡RkVÅ0€yófãÕW—‚ôÅ:PY¥A×lèîZ(^Ï<$“þL¸M+»í8c3ÀïËD–L’’vŒ]žüëv;^ Ú¬#ýA°y‹†þI%Š ÷£ëúZ<þxöí» .³Ü†ÇÕŒgžY‰ë€iÕdphYš'¹-k/B@¿>ð1<®¹ )¼ûn7€2¡ÁT*Çq$çÕÇöº ((re8¯ iqxÜno/\n*ÂåB—n踴fx<—AÕ Ëgã¹èÄ|£/¼Pâ’zxóê1½ú$ö¿¿~à›Ÿ€R¥€(ˆÄ\†&€® i@t-ÑãÐàèÄ©Syðå Ö®}ÿsÀÁ_ëhþÌÆÖ­ËàØyIW…º«¢Å³ Þ¼ñj ’µ³:(bpXVÑÎD’ŒFÉH˜üîwIƒ’‰Ão½í0!Ãa²7Dvw“¡0 ’ÀÍüûg{¥s€žnR1ýÿ‡¾q™šÄ31ÜâW–‘‘Hz¯¾yßêŠç7ÿ(ÆD’ GȆOI …;w6±/N¶·“ d*I¾þzœ¢_£ÛÓÀh„¼ØDÖÖ³r„ã¼Ö9< ÊPÜ·*„“§òAºáö±|yPa@ˆ–Ö»Ñ,鄘;÷*J‹ƒ¿! ˆ¶= gëÝPN Qx\ øÃ-¥¨(÷ ¹9†?ŒCdØ_ˆB~~Kµp@ÉGScúúÊPRÅÜyí ²`š%¨¯ŸÞüø“­³Maÿû× -Ysç6âÁjñÎÏ Äãý&ö!úú6¡ @FÏÍTœ;v„)Z_N%¬¤"bg²°ìdÄÌÌ 2š¢(Yk$9xr2¶öñ= ع‰PF3G^»ŸqcœD(ëÃÊ•f&´qÀí°¿péOD²Š¤ì¢C YÞž9µ33ÔzÙG¬bG†ùB+¬Òk´œÿ TZÖî2X,'ã$Bš«rçúµ^FΑ²+8Éô0¡º¿?Œ]¯¤‹¦S¹‰  V?¹Ban]®Ô°-[VƒÒR<2&Ξ>ŹuEB™>ÀðSßX‡Lrâÿhœ"'ˆUqx«„!|ʰ’oËÃuH™Ûb±ëÇ+*€5þtcy \J#زً³§O7ÿ¡2¿óýï‡)Ztˆ#š"íTų±ŒÄܽۿí&UxŠŠ^6_³Ú‡²rüù„q¤LRÓNbeB šº )þמ8Inœðň®;ûìsu1&î &倰ñ«ùè퉟š0B=Ö±¿|<T×FcS‚|bÃýnøòÊÊ â7ö+.Ëá’¥m„$¦®3”Nž;k+娋n¼§îpÁ™³)¹’Noe*1 í·æÏ?ÁTòlزȅ‹[r´@†åï“$SY¦¤ž9ã(’U7³¢XÙØ`)Á¥n¬L °¹dñ ¦ÌÛàÁ-ÓææÍmÔr*ÄÉnÿŸ±ý©c¼\ã-p{\;ôÖX:ìÚ*ýSGù®ˆGvïrPYÎÓšžŸ¼-(•âÁ·ß&5­#ëbbrª~yù±þ(÷íå«EnÚÔHÑ"#42&ƒt¨ë—ØÖN¶´ÄŠïLšM²¦æLæîp2IÞ¡hAþûÄi;‹ M]dqÉéŸÛ?p2ró6/Â!ŒqôrÇŽstÔ$¨ÕS)Ö›y×]ÇCäôöÀE¾òãk5*®¶^Ÿa™ä^ 8;Lâ·ÔUêÇ%qVWes3iYÎùT‚ÞI×€H&6·(µ`Á)B#ÜðLܤŸqb8Áÿ±›©«÷'u&N¼kÙäØôù?"$2ÂU•3Šv8Y]zÞÄ-›[ÙÕ©T°HÒ…©0HVX¦õ‹¸Aî}/ÁŠŠ£®rï—Ífœé)>úè5^¼è(*2•2a*Žîžî%±>c¯i’GŽ$¹}{€Àÿèrái¸ÄêéGùúa^m¥rÒÍÚ—^þ¡S}ôövÅbÆß‘do/Õ¯~çî]ÖÔ|ĵkøüó=ü´ž¤"á“ÉÄ#ø]Á`à/,Ë~"ad~5I²§'B’»>þø7Eør|9>×ñÿ—ÞF|ïcÌIEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/ok.gif0000644000175000017500000000010412533641120016451 0ustar benbenGIF89a€ÿÿÿ!ù,Œ©Ëí^ñQymuYåžPŠ#b$*µ;umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_eclipse.gif0000644000175000017500000000106412533641120021235 0ustar benbenGIF89aÆJýþû÷ø÷""ô&%ö((õ**õ00õ22ó52ó::ó;;ô­'rEEðFFòXLçö23XYêYYðõAA]^ìöDDöEFõFFwcÞ²Z™zsO{sO{sP{tO{tPtNƒwM‡zL}J‘H—‚F…Eºtª¢ˆC§‹B¬Œ@°>´=Ô²hÔ²iÕ²i飯³¸òÚ½|àÈÂÈòïÂÆÅËóÕÛôÜç÷Þèøßéøáêøäìùæîùçîùêðùíòúðôûðõûòõûóöûõøû÷ùûùúüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,‘€‚ƒ„…„.ˆ‰ˆ†‚.I0.Œ-H–—41“…,GžŸ54/,…+E72F+…*D)µµC*…(B  B(…'A  A'…&?××@&…%>9Ø8>%…$==6 3é$…#<<;ôöõ#…":ýþþ" }¢Á‚ >x`ÄpP ;umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo64.png0000644000175000017500000000631012533641120020404 0ustar benben‰PNG  IHDR@@ÝnAHbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ )-þy! UIDATxÚí[y\Eÿu÷»æ½ysì‘dt‰„lÈ ÄâADApUÔDý'T)j‰¡Ð *ÆÂh,‚  EA©ª€21A‰JÅh‘h !!„d³çì5;³;÷ëÏ?ÞÌî›Ù™Ýì²Àš¯ªkç½îïëë»ú×o)£Ÿ±YDI€F5 ’—%Ï’€4-X|Š€vºÿþ]rI¹ï MJ$žY¹—ÀKꦑ˜·†‘A!ËA‡g7|¢ðütKÀÞíY"€hÓ¦ ÈÐ÷¾×C#ïtYÖþ´àTiMc$óûÕ´A¼µôÈÂ…fa8…’á\ŽËø•uŸf|µ6¼Ø[×išÉJºæ.ÙÈrDŒ'hÕªé¢:!²æ ¿c éÏm$Öæ^Þcù75űéî)ÃGkb7#§›2LqvŠßwëFk¾”9¬«]Ÿþ®ÂðB)š/£\œLlf2õ˜igˆp€q€™NŽ¡JãS¿¦EK5ñµPxÓ˜]ÎÔØÈÖrœA“Tyry“R*'XÔaYO–eÞ±òR½ ¯•:(WÏyÀ ¸tENhkÏ¡; ¡¨rY¥‚HÎà p©§—èÐ }ùÆcô£Í¤(ì%@ÒÖ­‰¼ ÒˆñLÓ¬dCƒª_-OßâÄvuÙm®!–’p¬Í¾¸…ð˜XúmΤ’I¯üiÙ…ÚÙ4O-l‹ß¿c àÒ‹uõ_ô8Æ–£DÖ¡ë¯ÿj†óô¸Ì:V¾]‚‘[Š•iBÚØaZß´mg@Õö …WVíóÿˆ¶¿ÿCçEt}c—Ï÷\ܲ(®*7Í3í¡ð_Zlÿôlö‰`ðv§D%Ç*Å4õÍ'¯ÔÔ|±憅»Fvbïœ9ë í6ÜñßÛÚ•"]:˜„'­™uù|Ïz¥„ ß^Ô¤ž ïI;°£tÐcæx\i]°!Lƒõ‹S·xü0öò‹¿ÉYÎ/ûd –û:o°ãÝM Sœ‹Å9¤Rh)s³ ÎpÄ%{óœÖ3n>óâKîß¿ô:mß‘# îº{):(\30œï46Fè÷¡KWô˜C}*I«WÇ©œ|o¬9àM¬ ¥~f­ýÜÙÁ>ˆûHÑÂE´ ©›‡€$]w]”š›£H2­85¢ŸêêãÙÁAzwc‚Êɯlj«ß§gxqë—êëš'¢CššóòŸwOH 7fc¬D£: -‹¯W7’ EѤÇ0î™´)vù|›+Ù»w†å|A†3š2gôèÊf¯®GÇsBi.ä+õ36UcF•ªT¥i££Áðµgjëþ…†âªJ1Ÿ:Mã¹˺ûsk®Ô§­ãà¦,粜Ëõ>÷êMyçCŠè.MÍF6< 6ËÚð¦;¾wéJ–¢ìŒiœ`$ŠøÌ»LsòÈFLUG M á´ùý¿òë_k(´Ûwá…7ôëúë¥Û!:°oŸT疹߻¼È.Ÿ¹y,ž#55ç%Q ”Q›ei ½K—Ô8%ÉH«eýülù³œð2P»å;2¡œ Ú÷{÷wP°ÄDøׄ—髜–+\9øM<ëb¯|U…ÌÃt@Æ “H¼k#sF/ —‘¾/rx"ÌRÎ{8‚š— m‹±lö¢-dãè”Yã)nd™<ìèЪUn=KÐÌQˆ–.,“nS¾$ÓLR9ù\ôRYÀ°@š6 …'ôÈbÍU'ôaûŸº>xèw–gñ${<ƒO¤ä x ÇŽ Œ 6e¢JÒ!IÔÖ%‡Q³hŸŸÝãàÛ·¶YwAÕrH§8}* ÓÊÂqøãÓcu0Få 9úôgú©ù“ýùesè=ôÑÂ…QRÔ8×=¬\¹f€®½¶Ÿêê\ ëÊGéêkò‡¢Ï®…(D\ô¹@—ªÿ'ÀÀnr+814ãÈÍÉ‚ÁUßlCcbgwàG#K]Š#²ad,é× þ!c.âL <¯¼û‘S½ì¶àl¥RWn)o†á@±*3ÃWBÁe^~‡Mâztå{G9¢ÓwïD‘×-·Úö‘ »âV¿É)Höêúæ¹÷Ý+*ñ¼ž—ñzA€2‚MöJ©\0Jsžm‡ŽþkÍšu…vkj?ßo£`: Ü>éhxë—³TQ8æãž ½Kßaš¶›Ö›¿hˆ©êY$$#%ǵØö›OHŠrÁÚð¦4ç¹Ò•(-=Æ4¤dE‘®¾¾¹3|8j‡c¦b¡µÙþÚýþ»š¯nÖQ¥*U©JUªÒ;‰Îé þà‡‚Ç^Óç³d4ŒxLÈ0Ãh?áäb±%ËâÿÛÓ}ïø•ýÕ’¥µ'Cö=Ý>ßÉ„¢ôf8£cä”Aú ˆŽÃÜD*Í9¥oë5ôWƒ¿,|ðr,~û~BòØüùjÄgÌø|{SBTDŒÊ8ãd†3êô[©#¡ð¥o»Éwù|w&e›lI…">c+ô>ö–ø€Cõu¢.‘ØP›LÿÌÎYñc”Y!(Ë8IæÞ°2t'Ç5G2Nò¬ä9œ¡Çgþ¦ahèËçtÇ4Ìœ; j]4®Ú ê3ô–Ûó¯—,4ÏVþ¶EM5-¶ÿæ~];œöœ+™OLÕNž²œ“É¿^W󭤢¤ÇºÂRzö7®¡MEŸÇƒÁGÒBd•ûT:8kÖǦuò­–ÿŠ„¢tVÚ >]jªû}Ão3ˆ¾?eópMißFƒªJÏΟõ´LžÁì·Ã»Sj€2Ší)îsJ±©oÁ²žéÜ"(½‹/~"¡ÚÅcPmJ«ʪ6uÙ3ÒÏnÛàO–ªeÃN±ìùİ‹–æ¿ñ ÍÞð<ˆÀ< 'Aº›CÕ¢8tH¡.†°gâÂØ¤‚HbÝÚ|AÃêÕùŒ‡°êŠN:Èñ…/´€È‘¢(þþŒ‚@(U¶O"¢!Ø ¢Dkå |U+VFpÙå¼ÿƒxlûóe´^fà¬\èKáέY\uU+’‰“¸hÑq<ð@\ä¡b&1»!…åË @fRf¥L†)Rð߸ã‡^èÄG?¢b×=¬µd †Âbà¾ûLdÒn½•aãw±"uçÐu`íÚ â±84ãé§::t¯½–À⥥1gN»wG!ú|79i£©IÜÙ9´·h‚©kÒ»,«!#6luî}•Î)„똋D¹ÿpÀXÁ`Ôïb¿P|ÕP¨w›Kpò-QâœüobŒ$+ëÆ\ úáäfMl¥h!Ì>;´;£X”£KF˜Ôs~ÓôFÐ"ó<“ª0†¬bRÄ_ŸþÏã· cÏijà˸bHc}·Ùë3öï¹`Þœ©Í?\|¿Ãö·–^Ûx“¡¸ªÒþEK®žÎMÀ‰``MJˆ˜÷Ýû¡‚(¡(Ôfù7 †¦$<í÷?’ábŒ´›Q\UèàœÙל“txßìÙs£z¹³@ÑîÈ çÕ´öÓÀOöÎošw¶òÿÑÔô¾ˆáÛÓ´Ã¥÷]Å}0rÀh@SOæŸÛÑŒYâ´mßRz .`I_“‚˨®9½†žë6Œ\aäzu#7 i2©YIÅË• çÔjù·½åx@»eÝ94¼¬â÷óÕ£µuØà‘úS¾ÛçT}î¾ùf}áŽ?4ÌMdxÐ4æä’ ÄH4ÐÙùjÛ¬™êš¿=óæ6JT©JUªR•¦Ÿþö·ÉDTC7IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo32.png0000644000175000017500000000275312533641120020406 0ustar benben‰PNG  IHDR }JbbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ) ÅÑxIDATXÃíW]lUþνwvf¶ûÓm‡-(b+- ˆ1Õhi ôÁÿ|ð/1¢‰†‰&hâž”ø O>ƒ¼h ¢5ø Á¶üEj¡TJKÿw·ÛÝ™¹Ç‡Ý-ÛÒ6$ÆèIN&÷Î9ß9wιçœf¢œ”dzJñ‰Z'A€Ž67§Óó(4-.%ÎD£Ž³’¸,¡Í6ô`žv$ø‰)Ô>¯NdL+>#.‹©Óר„<‹E.ïæœi8‹ôÅâö¬‡/É3‘%˜Q=¹¡‡cx´¬Ë·,/°¡<Þºµƒ“I—/c€™(ßÈ„Œ¶t(t¨Œqg2¹tª™’m p*dÂ?Kc¡Ð>30ÉY¥úOÕÄË*Ùösà€ˆÛ§zè~ pxÓC4Z'ª=&*0‘¯ O¯]›Òuó] è2s,–㲂PK¡¥ D¡†¨S :CµÃ eäÉNÿC+êˆ-£X„Žª3 þÑqÔ¦­Âhk5ÈGIÈ’ÒÂ@ !l¾³ÙÍ~¾ãYBBØhúfμÙwï¹÷wÏ9÷œûÞÂÿóe›Æº{韊E—ˆÈw£--3†«‰Å¾ "_ÏÔ®25X×®îmݱcSî“ÅÄŠ&âÊÎ}‡ü|—årE5Ÿ·A’©\ŒÔ-ž°ææGõXÏ4ãßU$üeeȬbLÝÒ9®0lëºÂé¬CSIs¦–ˆÚVGGŽ3/å|€žÎ.ÆïÙ»D9´ kU"RÚ´b… –B’‡Dév‡Ò_ûŠÕwæ™f‘eƒà¢1Q"ò\QQÃC¼)¦ìÛ}.öû”€\þñŽ,¢á0¨p8”̶NÜí®ösã[‚õ Y´¨ADäù»®åÝÝF¿”b.œ2:%´‡wÎ ¿ËÓ( Cç¼” ZED ÷Žðøñˆ@èÀ‰Àu¹p!ö—{ YYùíõÁ^W+káBö±cQ‘‰÷¼¯DäÈ´Ç® ˜£˜Í››Å´†éÚ;jM7Œ– ›>CnÌdý¤¬~¡YDäà}g¦”Ñ[Ëê>Ž_.šÜÔ·³GÂrK—5I<)‡G,ÞÁéÓ¯ ¢”ôKóšê‹¹¨lÙÒ*)cáLK”ˆ¡¦ü±¼¼Y ó>6ƒ!cǶÉî=í"b﵂”H˜›çSVQÑUx†Ø´n³\·|õ©zik3#{Þè£83þC·”–¶¥-jÜö0!Ð.ßz±MŽ‹¤DäeË ë´¼ÿºò[ÄþûÅ‹Vò›/4INÎuñgµÉÄ Mòê«×¬PH ©ølGˆ¸¢Ñîé>_ΤææÄ–HÄLº[rsµÃÉxôœîË ýOü# †ÕhŒû_ŒGæ°šÕ±/IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo32.png0000644000175000017500000000252612533641120020741 0ustar benben‰PNG  IHDR szzôbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ' [”,_ãIDATXÃÕ—[lTU†¿sær:ÓéLÛ)¡¢F0QniÅ DÐÄø@l¢4Aå…hB0`ôÅ DjHÆ+FðA$MÀ ¼4ŠáÊ¥´ ª@Ûi©½LÛ™¡ÓÎí\–´¥µ—ÐÚj\ÉŸ³³ÎÞùÿ¬µöYëÀlÊHÎDssA*Øþ¾³àñŸ48Ó«U7nµERqcéógåΜ)=°Äñ{íÜøµë™+Vfgÿ‘õ õê™[u óò²=;C\.¯D«ªÖz-Z©(Š1¦QïìØa:JJ0¼^Ë—£Íy-Ǫ =&ÞÔ„ëôihiAbsC/\Œ{fv_&VoŒxGëZ ŽŠ TÃD=r$è).ž>fHçψ‚eX 2 ¬0|Ÿ2do(wšˆÈ‹£’‹ÈŒ®W×JðOa€t–îº3ª€xeåçÝSDÞ®¼\1zz—õsÚ 0*/¾é¬)¬úôÖ6…Þ!Dä‰öŠk$~<7é¤2¨Ú ¢Û‡EàúõŽOæ=•<0IT£›/«ÃÕ¿VûM2¦c·«hZ MÓAICK3Ñœx@IÇé4Hs%PT HGKK œ±;äîÙþý#À22iÄž" žðÌ«VE¸qÓçŸõpê””„);’ @xcc³.¾ø"I} hâ»ÃÕUilßÞÎîÝç.h@´ïK#}AÑÙ´©P0M;=èZ<$,û÷÷ ˆ¸ÝQ¹T•ˆHm­.Ùþ:Ù¸ñ– ¢(]R_gŠ¢$Ly¡( EE7äåWbR^·»A¶l‰Êo"]òÒšV D–,m–5k¢ÒÖf „EsÆDDÞpXÄä;}ìÙÂápÝK«á×ßBˆ8…³gíäçû8|HCQÒÓ}”–jØU•̬0¯¿–ÆsÏßfÛ6å?´SyÉ@!Ó ½W„>ßݧi¥¨®NPXƒß߈©'±©õlÚl°òÙZ=éáû2?o½,ËÀ4S€…iš˜†aé´4'Ùúî4çt,ÓDU½wѤdeÙ“Õ« þ>Ø•Îò§}|½O#ÐàcÖ¬¾ÜëâÄ Û¶†¸zegœT*Jq±EfV¯7Á’¥~öî18v,‡ù üôD=¸Ò  Õ¦¿'Ov $L]Àêƒ>æ _êîZ±DðƒÞ›}Hýíœ%O—D"òÞ—/‡~†ð âÑ`ÞÇž±‘ío—a)X¸P;”›§Ot„‡Yä›É‘:¡cWi¤¯“ZS]j®&Fîˆ+{.BtJø¼!‘G›–>Ù2…Q0eÆæÔ˜:!Þ±¾ 7'\Á·;,"rtì~&2¯¨h*¢ ËÎÁÔ}Õik›þ-J«5™ ZDDÖÞ_W—n¥¦Æˆ@÷¸s<Ü'âóuˆ%R>¾ÑBÄWV1êaB±Û»äò•øÍ‰Í7"Îòòˆ=àñtJmíÉ¥C­«×[s¦µã3¬Ëüù-™Õ“7XŠ”­_[Îèp!J2Äíɾ¯:-Ù<%cµˆ×­ûS22::ª$Å—Ù*}Ü©‹˜¿ü+µ‰DâhómI<ØœJÆ%ÕÛÛÃÿÑþ±ò¯Ÿ “ IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo.png0000644000175000017500000002566112533641120020244 0ustar benben‰PNG  IHDR›rD*£ÆsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ 7¢ó\× IDATxÚíyœ]e}ÿßÏsιëÌ$™™ì Y€1A¤ÕJë ´VKYDQ©¶j]«Ðª¥¾*ò«J«­-XY¬XÄVEd± XÐ"$$!{f’Ì~÷sÎóýýñœ;sçΙ;û$ä¼^çuæÎ=÷œgù<ßýû}”ˆ0“‡`Pèiz£‰®ö}"‚RjûKÔßwW_ÇÒþ#é8òZ<Éǘ&ç¸À&CÞ]}=jÇz¦)ÛŒ”(ÄÀmUßË0¿ÓM1„Ã=ê16Ò¤À ¡cPb@B0Æ~/f€’ù¾=ƒ´†XÌž PÚ^µ½*åØ¿ûOJv†è1°ÍB4Îû¦jü& ¡T‚RJ>ôe`ëزvî¤oï^ék?H®³ƒ|W7â—Ð(‰°ªP^Œøœ&ZçÓ¸pj\¶ V,‡×ÂÉ/‡t#Ä<ˆÇ!æZÀ©—¦ô2kÙèÄÁVÁÀ ¢¿ƒöì†'Ÿ`ï“OÐþÌo¥wÇvÒÅ"iß'í¤‚€x3^(hLgöÕ B¥ ´¢¤] Z‘÷\²^Œ¬ç‘K$h*µÐ£lMJX¦^‘|Õ~Âwò›ïß!ñ¶ÌÏçi.I~?ˆÊ¦‡òcT v\ïXÉ0Í ´&ç:ôÄã´'“ä-V§\ðæ]p!,Zhå?dzÀst»=¶Ùu˜ŒX,“ƒ_?Næ¶ÛØöЃÒË‘ AHÂnàã"5©Õ”­›ˆí–´¢è¸\‡œë’I¥Xù»¯Usßõ.8óLH§!‘°ìõ(Òn|° ‘Læ[!?Ÿ‡~ÁÓ·ÞBá©§dI¶y…"qâ˜YØ|yÇ¡3‘¤-•ÆY¿N~Ùeðæ·B*i©«@¹G¼{dƒ­Ì6Ëšäÿndǵ×Qxî9iôK¤ŸTP[¸ŸL°0  Žë•¦èXj—s=ºãqkÖ¨>õixýïA: ^|°L§Žmš@fmb!‹°o/ÿå_Ùþ£»duW7ÍÅŽ •ÅÆ#Mت‚ëЋs ¡‰oû#µì£†åË­ùÄõÀqmb ÀàÀ?€Þ^ø÷o³éÆhèî–¦’O£_"fBÚó1Ц<ã¡t¾£Èi‡¾xŒžys9õýW*®x/Ìk†dÂŽ“:¶©[Éf…"ìÛÇóŸûkÂ)K³Y’O,4¦ZÓ 6…#Š‚Þ˜Çî†&g©Ö|ù:Xqœ•å¼XMûÜ1°MÆQ*BoîùÏ~ñïhjk“9Å"ñ &2,5«wb§|z £ò¹µÚeˆœ %G“w=ºâ™ ÕúÏ~Þþ'ÐÐX‡}îØÆÈW‚H è%ÿO_çé›n’º»˜W,Ž ‚ÙCé†[­Qþ¾¼€”Rµ"ãyìnl`ÕPs?öQkŽy5ìr/E°ÙÀÐ5žÏÃÞìúÔ'ÉnxD泤K%âF¦,Óo©n·(ðµ&ãyt&’ÄÎ:S­øçoÂâ…–¥zÞ1° lQ´Böìbˇ?Š~âÿda6K£ï×Í&°U*VH§é~Õ+ÕiÿøO°r•UÊQ&G%تÁT/¸jý®ò7Æ@.¿ÝÌsù‰çŸ—–|ždâÃKé¨Q`°®¯îDœÜš5ê¤þ&¼üåÖóà¹/5°¢]ŽÒ ¢h›Ÿå©÷]AË®ÝÒ\È“ Â)³—qTe!CÓ–N°sù*õ»7ܯ8ÕR¸Y(ÃM»‚0"á+{²–¢mù‹?'¹e‹´äóÄŒôj§Š=EÀŸ ®ÜŸ‚ëÒKÐsüjõ²oÖž‰x• 7óŽü‡þ °‡U¶náé\Iêy ´thpä¥Å:kR†šÔAÀ‚\ŽÆí;dãû?Ï> Å’µKÎ"Â?É”ÍL ¿ù<´µ±ùŠ+H<ñ„,ÌfH†Úìb£ÓGù†ÈpóŽGg"NnÝ:µööÀ¢‘{KÛ eÀ¡¯—ÞÏþûïºK÷eh ‚YÈdÊ?«áMÑq ´Š‚5FkL¤–ï/'ÄhG@ðŒÁƒkBâ¡éðUS]´¯±õö?V+þá«ÐÐqÙàÞr§fuW²É:B›ƒ2}”¾ùMöüè¿dy&K²JãœÊq2X_dŸã`*Ig"IzÕJZל¤®ZAÃÒe°`46X«}Ù´ËZÿìÁÃä÷îãÐŽí´mÝ"}Û·ÓZ(2·£¹TB‡Ty7ô°°\c!J@‹a^>Çÿþoa~«âê¿ω¦FM”­~9M)5‹–ËÁ½÷±ñ£–»ºi-ä'72£ ¬eGwÞqÉyy7F6ç¸W¿Z5Ÿ{.üÎÙ0~KæãØH G^9YYø!%›}uø0<úÝ÷?ÀÎH:Ÿ#†$¢¼†zBž”R‘1-²r? EÇaûœ¹œúÏÿ¢8÷<«¡ºîKl³nlÇÞ½l¹àænÙ*sJEâa8éÔV0ýWp:qÚSiôÉ'«ÓþôBx㛡µÅNˆ£Œ£JdD©hJË€+§ø™(QÁH”@(|]]ð‹Øôƒ;(>ó´,Ëd™W,âÕÌ©”ÂD~=Úsy–Ùé¡d‚¶Ö¨Óo» V­BRÉå¤3 ¶’}}ìûüßPøîm²¢/3AŽÚ:#´ˆÍÄ<: ¿îµªåÝ—ÃÙ¯d ’É(ËiòÌJ*bî²Yxüqú¾s+;ú¥Ì+äh,ù¤‚‘Ôñ€d\—¶Tš–?üCÕüõ‚¦¦™µ¿‰ÈÌœFž^äwð›óåp".¡²)Á] H¨èÿÿxΤ¤µôxžlÛ$y&r×]ÈáÃH_ÉßG°ªaÕ9Î>†bŸŸ/ ½}HGò“ŸòäkÎfó¼féŽyýý k´½î~VŒ“(Õßï>7.›æ/¹ýûöý¾?cs>3/B¤PBv¼ÈæSO¥=’¼ãÔ܉€­¤‘>Ï“=éÙ´p‘ÈUŸEvî¨sÐ'´áÀøä»v"_øO-Y,{RÒçyâ+=î¾?NZö§R²ñ§!ÏýÉål;Ž.°0QÅÒÑAÏUWóüܹ’wñ•ãëèþž>Ï“æ4ËæWŸ<𠤫˶ïOÚ€cÆ8ß·íèìBz'Ïy=Ûšš$ç:RÒ#n<‹¯Ïód[Ó\ñÿâ/®Ä„3¸)ÛÉ0‚d3ÈoþGV®ödRD©q¬æáÁVp´tÅãòüÜf9ðö?A¶¼`©YP{Ç ˜É¢ï#™ ²{]—¼“çæ5ËáD\ Îð€ØJZKŸçÉ“‹‰<ñR(ر˜f°é%Þq ê¦Â¸«ç:–ŸçûpËÍ,éì íã4qØ÷Ôʥ̻/65Ð|ÁÛÕ¢o|–-¿QC»5Uù˜£>×Ñ6‰¥¥…¹×_Oó»ß£¤(8^¿¹úJÆ®,8bˆ‡!Ùí7Ý™¬Mâiþ&Plì ‚‘q’ÚØgÚUµé)žY¾LúkœÐ£†shm}˜Ä®¼’ã/¹HímH“s~[ÛDl¢ ˆ†æB‘î¿Oxq‡Ü4¢êñËhí€Úÿ°.|ŸEݽ¤*œìµVdù¬ç(:ŠÃ©óÎy½šÿ÷_²Íõ†™“‰¬à)œŠ¼ )âŸÿ±óÏW‰8=ìX 7NCe;ƒ" …"?¸ÃFB›pœœmìqšFÛ ¢|‚-?»‡ÖBÏLÜ%UvËôyq/Y¢üí5ÖJž8B(Z­ v›-5g.«>ÿ9ú–.S]ñ8¥ äTz71¤ý€-wÿTÈôÙ¨èIò?KÝ”mÌHÃKCcƒùœ`ÿ~I>Þ0仼"ëѺ ¶FFG2Á«®º V®°5*™å ÓÚÊš ±þê«yqNÙa2§ê×Ndªd’Øß?jçf<è©ú¾žažåoŠ%öÝ{/i?°™ë“ «Å¡d’o}«â¼ó!•>2)Z-®V–B¿õ\V_ð'ª;§äèºE‹êõUyxaÀü|žÜ=÷XÑf*ÌÓ¶šÈö±ë¡_J< &í]™XŒö¥Ëh¼ê*ˆGIGIµ}¥”- ØØ@ë'>AaÁ•w=Ç“ì6ÀF5倥˜šK%vlxXÈçläÍhY Èqpˆé™™0„Ç'~ð@øÐX’T l 5½±8§¾ûÝŠ%K£ªÝúèªÄíDjë|^þþ÷ÓžLRGĆê¿Ú¿\cH!no/üjc¤•³—²U}ÄÏ¡ÁÜÿ ry‘b ÆÐDé¦èqÊæL–Z[I\r‰­Ô8ÌŠ?X*ž^HïÊ•dcî¸d7QQ¦€†D°÷þû P°ñw“ 늄ÃÚÛµ\ÊEµ£æþº5®c9âA?{ÌÐâý.‡ðqcadq”‘¯,EÄŽ¦ˆ8šœão{/4­¢$@0r{gãµÖ®u_Ì$!½Š¥o¿–Íßø%;`àmAýîP,ÉÞÇ”\VhVxPG?ÊÊŸE´ˆ?U ­ž4¾æÂ‹~CÑ?-¶ öp×±©\–îG•¹¥=‡?øj¢«®ItíŠ °ui矼Žì’¥*ãyÖ%¢Õ¨ížM×jÃÄp÷¹FH„%œŽÃÒûä&LP±-Qíq1ÏÁZ‘É)Mg"Îò3ÎPÅTš¼ëL¸_–ûbÕŠnþá+g๱šƒÀV*jæ6ßM±tš ÚfµtÒ‹Ú÷y6!n¹‚ÏÆXÛ&4 ÷ÑhŠÚ!Ô zŸÒ‚ Ai¡®~Ìൠºþ\ã>›’„xÈ =°êµu•œŠ(%­1ŽBŒšp¿JgQ*V9‡Ð4#’¶÷KÕÌ(Ë”•ÊâèNP!˜FÒˆ$ÆU¤ò(§ÛŠfN{dÌT§ VJ÷³Ñ)u­þ‡(Uˆ_ĩոiŸjwƆϼyyÞyÉrº»Cn¿}?A°,JÑ”A÷µ6¹è¢eìÞ›ã§ww"ÁÒÚÕY\g7øÀ©xn‘ÿþí­äó‹#@è¡”Då‰Çð¾+NÂuò„A’o}ëüð¸áÁætó–77±be÷Ü“a×Δ/Jåí³”oÿ7†qÕιî:‘OZD;dÚæ³\¶É«Nß@>'A=‘ºÓ)ߨ¼­pà€¢0 T Ù,ÃÞ§5 Šƒ¨€½–½€Ž“C+xq·5T_öp½h¯Ñ† ޳ƒ+®€C¡§«œ߇¦4BÛ‹6qÞ‰X±ªÃå3DF­¬Ôl@”* tÆž*Â,_‘µ>̇>_ ŽÓ1›|!3}ˆ_QíÀ Ÿ m%Ǫ¦¹²\Ï]ù  ³nÿ~g¾N~Y­²U‚µAë §ŸÞÄk΂۾÷¤ºQ t0²HhUÞ$Ù·¶ƒq­8­{pýx±ç9ñ„>Þð†VÞô¦VN?]ˆ%žÃuw¢T´È†´³/¶•˜môì=‡ëí@錕E+ú>ݯ͊‰þ"3£È¿µç]†•wLhEžo|ãGˆ+?ø;(‹¨„ŠdÁ¥ûøÌU¯Æá¦[Š«ßÄ#2T UÕ¦Q¨’ÒYÔÄæÍ§qåŸçm± ©è³ÒÒÿ|Gw°ñ‘ån®/; ¼€ƒçä—¥Q”úÓn":Êö–!@uØ»'Ëý÷Á¿ }”î¶”OJ(ÝÉÉ/›Ï9¯‡Ÿü4ÃáŒë› 5ÑjäÊ T†W¾*Å÷þs!kO‚›o*pñE9ÿïçK_ÚM" _¾Þ{ù«ÑºÛ²ë`ÕmüÎwàúëwÐÑ×_ÿ×_ã7”­`©²ÿTÖ*«I!Ô`“A,û£Ã0É-ßydÞ÷þWົ-ËÑ9ø/vÉÓßû.sŠ>Nd[ ‘1 ”)~Ös8˜Lóæ+¯P¹f(L’ëT9° µG¦¿n%ÅuøÐ‡âÖ4‰2v¬VÝý¸jܺERAˆ«‚þÁªç¨¦¤%Ç%ç:¬N-ïÿAãÐöIþ=BŽZ»ÆJ@v]÷ßœ»‹EAvDecP™…ªqM{<ÅžÕ«¹ä/¯€(Å&à¨o­š†ì+çVSíÊQ“«Ðy½üþkÒì|þiæó¤ªJ4I…6Y£'К¢ã°óÞ´|êM¸«-Y®,.SOjý>ÀÏBç.ÜýeÖv³ ¯_»‚ ÕoLwc ¬:s½"Ö ±4±Š‚ƒc¾:~ «•ÁÊpŸ!g‚2ކ7¾‘CÉ$Ūb}ýÆþz+Ž0$ÑÛK÷Í7A¶ohE5¦Â‰³SC•H+•àÛ73ÿÀÒ~0&í¶Ö÷"‚Qw\–¾ñ )õÐòlfäÉ™Ócpxå+ —/£àN\0PbkŒ5•|6ßþŸÂÖ­P*Z¯¸ ¦ÔGâÑÏM`Ÿ{ö°éöïKk!?)Ûc–KŽÑÚg½Æ–† ¯*®ë^éãÌ0W`7†M&YuÎ9j0eÓc¨ ;´ªd£_bEGm×\ù‚¥nuî«p$”ÖÅ¡«›_ü;æôô ö00¦’§åÊ”EI+ºãINxÝï)â^”®¦‡PÆÊ¿ºÂ‚0A°M顈'Yxî[Éz1[v„’Nõki!óóz{Lü›oln„mrŽ$9Í@@1ÿy]=$sKÅAûFŒ‡j—÷*+:.‡’IbçŸgK©Vì_©XLvö•®^é£Ë2uîŒRù ­-©>åTR«W«Œ«ñÇÌM‡¾W xÆ0/_à©ù†ðô&(˜5;·Œëˆ¶/aûvžþú?ËŠÞ É*¥j¬{X©Š=ê ®CpÜqpÆ–ëÔ;’uÍ4Q6) ^œÕ罕é…Ix³Ëý‹;:Ùý¹ÏÙýÙóyKŽT ‹pè0¿ý›¿¡¹ãsKEb¡™”yð•"ëÅ8éüóép§Ï§«)Çè²L¹k=ÈuàO.âpË ^|ò,+¡Ð\Èá?õ¤¼ø‘B[»Ý|¤¥8ÕQclåî®N~ìcÄÝ(s‹~M 6–p*ƒ’ë’I%™sáN 2Ù@† ûjü²ne‚éõR{.,]ÌÉ\ ú¼8_]ÿjUÞC24ÌÏç)m|TÚ¯¾zº g¬rSð¡7þ/~‘ž’%™ ‰`òdÐ’VN$Y÷GoS,]^¹–Å àX %IDATÔÈh#P¶©ÙmÝÇq ÕȼË.#7wŽÊ¹&²ïH”t¤ C÷eèþù½røŸ‚ö¶h÷¹¡í¤¾%:ÅPÊ­äCw7ù«®¦ïwÈü|×H‰Óš2˜Œe½û[›ñÞ÷>ð¼¡!ðS ¥W>oÊ)Û ÕRV/á”w]Ê¡d’‚—5hÆx¸ÆÐèû,Îf9üóŸËÎöì…\üÀ–i-Î#œTàC®mûyþ#a÷wÊò¾>J>.j‚;á˜þj÷ðXwñ;ǯ7v$Öú#ETغþ—¾‹¶‹èó¼A”jh½ŒÁ”³-,†,ÉônØ /¼÷rxöÙ;Ühšê$ìdR÷„vg¼¶±ë²Ë‰?p¿,Î爇–¢É´j»ïAYVƒœëiš£šÞóîÛ7bf" =-åUW\®ºâ ŠŽC¨tÝõ5ê¥p‹rYO?-O¾çÝp×]ÐÓk'wš÷ÙdcìûsYèí…ÿ˜ÇÞóœ'že™ ¥ŽX{šž$Ê“wÚRi^q饰d‰å.3±Ç׌lS†H©„ìÛÇÖ3Ïb_:%9×™ð¶Ý¢Ô Ï¾Ò’qiK%åÙæé}ç%ÈO"Ý]öýÓÑWSq–ûÝÓƒlÚDße—±©¥EÚ’¶ÿ#oÑ­«ÎúÇe_:%y²}’Ï øG™ÖyŸ–—Ô씤/ƒÜós~½x±LÆ'´z8Âw¾Ò’÷\ÙÕØ Ž?^üë®C´!½=H6‡KvŸöáö¶7ÐBûÜbɾ§»9ÐF𵯲qõ*¶55IŸçÕÙDZ­¤µôxž<¹ Uäç÷ }}ˆïO;ÈúÞ&/ßÀŒÌ™k… ”|ÈféøòµtÞx£¬ìííg!õKfˆý©,ÛU¶L”Ý›4‹Ñ‹;áµêÒwÂy-­JBÌåNžŒP ¡‡ÎÃp÷=ìúïPÚ¶MšJE‚XàF,])…¥¤Dý‘¡ÏóØßdÅ;ß©’_ü{hl²ìSÍŒô4c`‹n…äƒÙqÑE$6=)óŠEAXGŽTý`«nFÉÑd½8‡’I:,`Íùç«ÖsßëO/nÏåR˜šrÍӪŢœþåòø&ò˜Ð*#¾Ï>MçÏïåùÿDš¶±$“§©TD39{®Ö›¡†¶T‚ÎuëÕ©ßý.,Y ÉäŒ*ßjÚ3©úAg°’ËÃÆlxßûemÇ!æçóC~¢Føü/‰-7Ý"Ë3šJź€2Û û ‡’£ñµ‹¯! ££ýÔ`{¾ŽÞëˆÁ‰DwÏ1#Ä‚WB¼Ðîí9G¨4¡Rìnj¤ù½ïS-}54¤!šT¬^ª`+…„·é)™ŸÏ ‚A2\ýy¡õQ²á’é®2¥éÿyÏ¥#ž ¸þuâ ÿ+W÷+ÃŽû P¸)¤lÃPQ}ÚÊÇ­`Í¿~“¾µ'©CÉ$%×­ò| G¹êlGå«v‡N'¸DÕO©+ï/S´Žx‚/_§Nü×oÂÊUh£¹£f c )›?ž¥‚ÂíØÎÎO~Šàñ_Ëü|–thpåŒrM”ò‡BNTÁ©f¡›ÑÞ™Hœ²^ø¯7ÀÊ•C)Ú,Õ¦²éñ?^E¿ÇáøãYyà $Þôµ·¡‘¬£ÇH¹ÆGÇ [ÝoUÌUg.Aù>%h¾£8˜J“;ç÷Õ‰ßùXµrdЦ¨ÿ«£N  E8ÜAϿȮþPår4ú%âaˆfj*^˸wnŸg£.Ó††@9ôy1%“,9ÿ|5÷ºë`Þëù5’Ã0“e”gØF`»&°~Ô\þã»<úµ¯ÉêÇi-Ðf¸¬zÙãÔ±ÑÉû@ÊcÑÑôÄãì™3—Ó>ù å\~EäÓõ@»5ÙälªB1ëÁ6h°üÈô«¼pÍß¡ŸN拤‚€X(ƒŒ§J9Å;2Á†Ž(¶hJŽ"çºt&â+Wª“¾ð·pÎ9n°ÔLëaQu lã¶ÅX?d¡]Ýìÿò—h¿ãNY–ÉÐT*èš(› 6hûQ–çF_‚u£uÅãìnj`Ñ[ÏSK¯ù<´Ì·ò¬ãDAS¤¨½”ÁÖßèr´k& ?º‹g¿v=Þý2¯X$í—úê+q$-T¶JSÎuéÅÉ-Y¤Öìãðö·Û²ã o à9¶‰ J9œ'ô¡èCW…[nå‰[n–å‡Ó’Ï3ô×ŘiÈXœëБHÓÞ<—5ï¹LÍyß{­ë)ÃVD`›2l1ÀaÆó%é´húƒ0ya;×}™½ÿRæ}Ò¾O2 ¬uÔ Ì™[¹Þ\ÞqÉ{]ñ8K^÷:5ÿ㟀uë •®ÛÇ9Pðئ§‘,ç—lŒ§žb×-·²ç¿%½½´ ¤‚°?"¶_¬ñ÷˜p”â{£=[Ðd<‡CÉ$m ,xýï©/¿^ù*+—ÅbuÉfª®©{LA˜"Љõc•ж¢ÑömpÛ÷Ø|ÏÏp::%í—H††Xà N”M_·‚R¸†¢ömPÑÑøQ©Öœëâ·´pò¹ç*}ñŰv-¤ÖeçÔ¿Ï1°M—òPfRa— C›˜†ÉÀ½÷ñäíÿIö™gda>OsÁ*Õ&“ñS2kˆ˜(Pt²^ŒÎDœÃ‰ÞËÖªW]z)¼å-6îÌõ¢¨àˆeª£kWõ£‹² ·”ƒ Kí¶nÿùnØÀÍ›%Vò‰>ž\cpBCŒ( 2´”O!è²[©j³ Q X† ¥ñ•Âh—’ÖV.‹'X°nZôÚ×Â9kרâ.e7“où‹Ù¡mµ`{¨pKZàe¹}½ðÔSôlzšÏ,_Ç­„5k`Ñ"+àÇ<+ƒ¹Îô¥ÒÛØÇdJÇÌîÿm3¤ A”Š¥æ•Ó}MÄ®j U9BEW\•¶™Xe¹Kk[êµ|šylÍ_Ú`;"Hð1°;Žc>ô±!8vL×ñÿ#&€è±5ÙIEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo48.png0000644000175000017500000000530412533641120020745 0ustar benben‰PNG  IHDR00Wù‡bKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ',ý< QIDAThÞÝZiTÕþî{ý^ï3ݳ4³°Ê¾ ²ˆ ˜ä5U‹ø' šÒ F«·˜*£ q(’£ ‰•”¦ÊŠÅ„(Š@\t˜™Þ÷ý-_~tƒ³Àà$]uêUßwϹß9÷Üsν÷ÿï?’£ƒ¤m |)ÒMr&ÉIg3®AN&Ùpº~–~ÁëÚ”È?ÞÜîiê/ÒÈf …Ý«ýŸépÄrGÂáÏuÒ;¤n¶¯Ê+œ>Ÿ™ÖéV WsÏ[×ß_÷(5Uý]ÁtMµ¦ÈÊŸ¬Z1êì’¢éTì«@ðKÝa¤Îç3dw…ÍåVU Q»¥D€äeBˆ\_E ÞßÎÈåWÀ*IÀ°¡0gÌ€vñt8F‚½ºJ¥4L™4²á0r>ÙËG»¿6À g±@™0…Ùs &O…³¡V¯²Ó3Ÿƒ–È èDáP+lŸì†¹ï?P dFŽ„ïõ7žU&N¼}àS‹=ulÒD ÐX˜˜˜˜(S²Ü–+÷9ÎÓt€€Y€©2_¼üLÌÌÔšež¼EfxÍí#ž>P¿Ÿyàx¦,È<•DO€½öëƒØ+‰ý €±Qé}°óõ€—Óïïx22y Í^„žkÊŒ<ð ’œyF hÁ`}zãÆLVUÏ;øã UUÑ ø?ê ¯Ô£%›]®mÝêPŠÅ "Œ öhñææé$§–ÁÜÿc²Ü‡Ÿž2Ç'Mnê7œhnjjPUð¼Ú@PÂ-[+N§À­m À ï@qBÀ™ 8x게_tII Ò빘d£âXZÞÚ:áè1sùÒ&,J}™™'ì úò´=ª+{ô#/.Lzø ÐSY³ç»[Z‚J4êà`”“j¿JÁn(Ä ÌLGG{v·Û{u!G¿w¯áT(J“&¥!ËE(ª@.+ðÅ~ãÆe!:ä@,f/ƒ3!¤¦LÎÁ7DBþØQŽð2ÜNÇð>ò€ÌPd¤S6<Ûx¼6¬]+ãš%Q\q… µµÄG»ZZbøô3€†ë®McáB;–.ëÂÍ7;qÕUQÔÔZðÂf;K}Õ‚u÷å¡U¬]›ƒ¡Ù±ëÃ<ü~B!’PÕ.9 0nŒcÉ’,€,\FA!/™}&²dÂ,7 Ðt––me+ŠEÂ"[`R…$j™+Û~R¦¦]Ã`èÕH%qçX¶´Bisô”œAªÁ¶m2Y; d€Dee O=¥á½÷¼x»Å¥K#:4‡ûîŠ[n©ÂØ1: ŸWÍ˽‡Q“@6Ë“b°ª[^t¢Îçž})ìØaŵ×u×¹ ªê™¾ XÐÚª‚$ö}*ãÀ~ jjd„ÍîÂ]wéðz„BÃòë hlV®ôc̸"Öý¼7ܘÀ¦M~Ôú8|¸d¬BQ Xè#He–£G)Þé:ðØ#!Äc.B6^!ÊqÚÀw(ÈdÒh=ÄE©¥È €"f_Z€I€ß^nÝr“ Bä˹GÇĉ:ÆŒµãÑG+‰ÈåM2’)ÂáT`²S’KÔg"sºDy€Uè8ª ®-û{;à´êp:Ã5ʃhLEÓÆ6_œ€F›=ÅáÃl¢¢d˜´(9¦jÍ09yr'w튿܇ ô1£3l0MBAo)‡ €,åôBÞ—㔪 \nЊPÈvJ* 0-èêªêçTʉTÊu¢-Ÿs¢½Ýu¯®YÑqÔVªIaµšÐuCëÕ…ÒiýýKg9¢@®,¢”I––Ÿ85;òøSÛƒ<ÞÌ“Þw¯qxrÅÖã?Jà˯ªkTd²Ú–^عóƒÄüË=¤Bj‹8“Lô¬δt:>AÔÖsçzÓ½*°dÉâ._]°@Ð/ŒS5až¯X 3ZÚïrªGúÙRZ^ºõV@~Ð*Èo·1NvÚM½ªêY~½tḀ nÿ©¬ØÞo×x¼(HÚ^y%EÕš¼`¬?dH _ŸñÁVWWáɹóüŒo ãœ'ÆLróæINÈéÜœçž G€!Xv^Èà̶¶Þ<›{·æÏo#Pó»IŽ?ìäÓ•'»Ε+9o^ m#9à“…ò»Îy|>N!EÏñ:0èv·™mmZ‘¤ëÛ\/ Mã¯VÜä§¹òIß9XÀRÿÚž#É©ƒqGæM%µæÍë ûö³Ð/?)¤8<Ì|ÞøÙ`^ôhk+´/\Ô98Jô6I Ä5kCL¥§In-CÒÚÞ^8vÙü…»ÓéCq˜="É—¿Ë+ׯX¬xhÉ’ )uæ®ÑïŒi¬¨ˆðÉ߆HòÏ éß¡æ”LÖüÃúõQVUùÏj6¾¡çÌîâk¯%‹¤¹ôï|·™°d2úºÏ>/æ,l'*ç‡>)ï©¿ñu’tŒ?¦ß¯í× .:/ub6_˜Iò«-/E‹&¥Õš" õ‘ì yº\!~ÿ{Ǹgw6KšÏ_ Ÿ#è·¥Òú[¶Dùã›"92H N K C!œ5ËϻåíT'ÉgÈìœÁ¼Ë%4;`¹(Î?ñšƒ_ʶ?ŒÀåR±haªªsGÍ6»å!Dûÿ‘È±Îøj’÷gsÅ_¶¶vŒüŸúÂ¥«+yÎ6Ôÿ¼V'ÕŒ"IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo.png0000644000175000017500000003105412533641120020572 0ustar benben‰PNG  IHDRy}†kÌ_sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ 6ƒ®ËÇ IDATxÚí½yœ\WuïûÝûœšºªçAÝ­©»%[’-KØ6fȵ ÌòÀ aÎetr!H !/À ÉË%“›<3Ø&Á 106žÙ’eÍRRjõÜ]ó9g¯ûÇ©î®ê®êA–,Û·÷çs>ÕU}êÔÞ{í5ýÖÚk+aYmúvŲ›ˆ ÔôtÁç(u¦}NÝšùž" ÕYy°?Ö3™7? ¾xÓg@)δ•t©Ï§`þB,µ(Õ'¾äw3 m¹Ä\lLÏaÊÎJSrÆ=8ó•õ\%¼ç¨s×ß3çÈsÓΤ?úü-¯3'ð¼…)goúŸœo–ÌIˆåöcIœ¼àꘜ˜àWwÝeYTT•SSSCcÃ*ÊËË©ªªZðY3ï—ÉÙ‹­hÇqH$œbxx˜áÓC3÷‹õõõÔÕÕQWWG,#œ µ”±æµññq¦¦¦<ÅØØ“ãcxýë¯ÍÍÝsï‡z®«Ó¸¿¹û.®¾âÊ6‹uà9$‡†è8µa,‘èTAÏ@ee%«V­"P‹… izâ{zÒ‰©TŠT*E?®ëb<ÛšëkÛškk;U5`Œ¯ -…Ÿ wxøÚ¾á‘{¥À`Û6ÍÍÍD""‘Ñhô¬q`&“!ã8§NbrrKiÄÉR¶µ47wDëjÁ² •þد~ø{¿óúk±íàù#²ˆ‡RЧŸÞKm³¾µU8q*+!ZÁxÆe$'>9ÅÀÀÀ×=áF­5ˆÆ(h‹h4JY$@0¤¬¬¬`Å{žG<GD0SSS¤SYŒ1³¢Ô¸D"‘ÛV55¾# SSY F “túà™½àº°};¬[á„B £“$ÒNõü$•J]¯,=Ó¥‘P˜ŠŠ ”R(¥ˆÅ*°,k†óE„d2I6› ™N‘H$ðã/À=pà§÷í£cÿ³ Žóæo„ë®ãáÇU¶l£iuóù!²ã8ЇŠ' x.:×·ôÆlùÁ`U÷=ö„zõë_‡mÛÏ?‘÷îÝKƒm³zÍjù›o0úÝïÒ29‰6K) ‚§4Ë"eÙ$‰@t8Œª¬ÀDb”Õש©#RSM0ZN0#+ÃhE¨ºÆ_é4éñ1,¥HÇ§ÈÆdãqR£c$ÇFÈŽŒC"Žš˜ ”Js³D¨çt]4Ubˆ¢À q,EʲIm¦,›t8ŒTV!± BÕÕ„kª‰ÔT®¨À. SVQ‹"RQ ‘0xg| “uðÒYÒ““¸©©ÑR£Ã$†† ™@&¦§SD,QÇ#ìe‰¸‚6Æ_+ Œ‚žò‘÷¼æ¯|™¾>5à¸ìܹóŒ‰|FËc||œááav\y¥ðè#týøÇ¬Ëd°Ä ¦ "ÀVž‡m e.Ôd³8ÉÞØFkÜc‚ I+H)=c׊Q9hr„,¥PbTaО`¶1Xbr¯`YÀÓ(—V†€§Ñâs|…Ò¸©4îÄ$žRxJ# Ù9}4Ìêl%³¿¥§Ÿm¢Ž³äI,ÆÓ+Y–Is…´.•S§í)yÏ4/¼ø§õp1¹ÕÝ'1ßÿ_ -Ö®nâøÑcçŽÈžñèïîæ¢  ƒƒtüð4&„]³,qVŒKE¦ƒ@êlBÑÏ9îQjqª³Á/Eõ„<¡!™âèw@{;/kk•îîes³^ª¸ì8ÞI[C8Y’·ÜŠÛÝMÔuyN\—¿’§÷…óQË^”Žz™3 †LÏKÀ"žG`d„áþ²­ ïh_Öót±ç®2×uéêê¢õ‚ …“½ø÷§*“%膕vŽšø®aEÖ¡óWw@g'-›6Jwg®ë• ň­‹‹BÂuvvÒ´ªÁ_ßwÞIEo/×yAˆÕ—n›µÊîKõàÜñŸ Ц¦Utvv.Y èù”7+ÂCowÛ7nqú~ù jS)BžA­Pâyi!ãQ›JÑ}Ç01Áö ¥·»« @³JÐó)ï¯ …oòSŽøxí#0~èåN–€yaeL¼ô8Ø×éJ)Æu’ÇáEM8Âððð’ð†E­ëööv^ÖÚ2J*IÏÏ~FE6KÈóP˜D¦ÄK½‰ˆo„y†òl–ã·ß‰$[Ö¯íèèxŽ.”‚L6C*•"\U]ÍÁC =üa×[™ùsÚ ­ò|W®Ìõ}ü1Øû4¡êšêd2I&“yn~òÉ“'i¬«õCfwþŠªñ1"ž»B‡óäʅŦM½¼÷¼õÍ·18XŽˆ5óU“/FÆ~þ"x-?œï~-Å<›žw”˜ÔÕóóŸ¿‹H¨Šñ±©<"—2¼rmjjËŽˆmáƒpäH޳uÞdXøDVRœÈJQjÑÁYJáå’ÍD)”È’ï_Î$æïly)ý=ûDžeﱉƒì?_Ô&CÃ]jÍÚU9Il³žGä‘‘ÄD1ûö¥p½µ¸îšÜê#~6ùÜ”™óZêóÅ^K~Oùû˜ Ö=wîë\UhúÝܸ•R¸Óѹû;;?Ë÷B`çÜû•çÙgÇxÍk«ééNä©pU <Ï!­F ìÝ{$àO…(Tn‚}ea ¯¹fÝy1jzwÄr‚X¢aæ÷—ƒ Îé_î}éÜ, Ç":÷ÛËÉyž¢sâÙgú@Ûe8ŽStZ ˆœL&±,‹ÕÍëH$áØÑaD3[Ú —–6[”ðϼäßZRý‚óç;cqüø©ˆ ‘H,Ž]§R),­‰Eaè4 fsœ\‚³ò¯bc—EæFf'iáç.ÉŽ”âôP ô3ï½5àg¾'þ<ÆÔÅfp(¡6×Í.nx¥R *+Ëo³þf»©I!o¬òP¸(•@ë8(§"“¸Ø !E$X(2h{ErŽ_ÀHÉ]ˆµ  Š,J¥Ð: *…Ò"% Á‰øÏ4e¡B+•BYãh•ʹ-y5IT)¤i¶ŸJ)qPˆ…‘Æ«ÂÏ/‚f*á‚@EeõSñø`M]]C"«ébÅøø8M ï°-èè'-˜pE¥'Ù¸ÁbõÅȼŸQ8®fbÌãäI—D¢ WjÅ LrÉö ååq'×MÁH%S“QöÂqê‰ÉåÕ9 ¨,–Ųûimu¸øâ:›Ê Øà¸pz0ž}}tv·¼D|B+ƒ˜äâm*«â(q|b•¢rÎ’õ=‰*:Úã„ÂÖ¬õ™BICáC`¼ðŒ<TË“îK»]ṊTêë£Õ½'Çhi™nÙù"Ëq"‘èêcÊ0ù\¥ ZeøÐ‡×óñÕã81ž?vn7§’ ß÷/~ß½é)‰5„CYþæë-lßáﻞîM0ûŸ…·üî8ŽcJÈv…¨4Jű­Avìˆò‘ÿv9¯}-Ô7ø»Kg`YN^ÀÃÀ÷¿ßÇ“OÇóšS  |ù¯6°ë~¨\Y¹]²Þ´-©ý=Ó …—»ïÆ?ɰaCˆ?¼R°-¸ëNøðt FÍì†8cØW,À“Šœ$,áXIˆÑahld&ç«È]³™žçÍÔÎÈ A)»€› šlR)àeQ(+ó· 'â0•ð'¨± ^þrø¿ÿ þŸ¯^JÀ>âNC*áON$·|º@¡˜–yëZ«8ûþ`3·ÝÒÂûÞïo#`bN Âä”ÿ~í:x÷»à–¯æc­#`wûb­“„Cþ®Sǃø”¥S~ñ²¨ÿóÉ„?žDÂßE[†` A6é4XÊ{ 䫀ℕY·FŠXûZåeðûÛÞ,=NSóïyo`|Ž÷2;#Z4"!††}Fqòv³äÛv!’ ŒÍÂÄD$4ǨòWÎ?~§›o>Â{ÞÝÊ7n%‘„??O<1*Dãªr¶lŽñ‰OîdÃFxïûàî_oâ×wµóñï&=ÎW¿úÞð†ÕôôÃûÞ3[I¥êòܤ|±é¢”ƒe ò÷má«]MYØß2øèãð³Û°ÿÙaN NÐÜ\ÎE5rý;.dçË¡¶¾ú•&”j⟾÷,Yg5gÆæûæ7ðŸw<‹¥bÔ5¤ùñ®§¾nÿé_ûÚíxÔ°ÇøÖ·ÞÀ«_Ý€ÖšïÞôsþý?ÆøÒ—~Ÿ·¼%›™lÌr»ô Ò™".šûwy(=ÅúÍM7mgd~ø£q”ª)Z Ìäè11æ3M)ëÚÎ÷¢âñ8 q=ŸL匮<"« b*õŸ¨aðt­/ ôœ¨¢»«#Qº:?>AG×An¾y+åðŽÿ«’ûîM30P‹m׈ÇPÊçàöãŠx<ŒëÕ .bl9XÖÛ·‡øó?¯%„¬ ÿüO_ÿ›‡«€&::<y4Îm·>ÆÿøÌ|ä#`Ùpãçáð!ÃŒ‘Ÿ]Þ×_ʼnë1&ÆÄäžçxl¬šî«pÝ5ضE"†r¦¦b$â)ÆÇE&>ýêF^¡~®—«R €Ò),ûŸþôVví‚ÿø)hÂsÕ<í?]ƒ›vÓ‹[×¶mƒø5J&'RˆT‘ú®GãÅðh@醙Ũu3ާ|½'J9<úÈS;æ‹í !6d²Õ¸&…ó«Bx`Wùß3ÑuŠ@`€?ºárêWùyo» ¾ø÷ÉnǸy@Pn–ÓCq¾øÅ{©­}-׿æª þø/á±ÇvcÄÍq q<1X–ž_ bž»†€%@™?ÁÆÂxQD Z«¶§rzÕCT[O tœpÈòGp\ ãU!ËÙBá`YÇ©¬ÚŠmƒVƒì#ˆ”aÜß -XO"ÆÆý;[¦jn<9?š%ʯْ†©x&7qº„]—Ûý_4ô¨‚x^ˆSýiô¥aBA°-Að çCÏÑ¿Ó"-OMhgó&xÍkÀsü9ßü›Ý8Ù‹S…Rvž>T01•€'žÌð“[°oÿi\· L¥Ç¹êªFÞ÷Þ·³c‡oï¼üå•üãw®¥³³Šo~³‡Tªl5ÏA—¾‹;6¾°±gÏóœ\Å!Ä.éìÏ} ÆCcðT…“ã¾ Ö¬ cŒÿLϵrÄ+ÔMZ <¯Æ¥R)®¸r5UU¾î¹ï¾]Ý ã5çtëÜ } !„15œ81Ì]w 7øÆÉ®+ÖðôÞ8èmø49ëUÏÉgÞ{1ކê8=F"hÅQ4ePz’P°›?üÃKùÔ§ü塚¸ðË/ ñ¶·mço¿•åûß?Œ§êÑ8\´­‘믇`Ð7ú6n ÓÚæÄ ø»¿R…†¨Â L°X<Ùä:©±´¯c’IˆO¥|"«¹AkSˆåh’u'Ak?î¬ÒXöI^ÿº&.ÜèsÌÁƒø+±¤;0ý3V‘Ýà­m5X_?ûì)€(à~]ˆÅ'žç5ðÌ3cxN5*^">÷Ù=*É:Õ(©,ê~̺–õ|éKÝ(-8nž©F©‰ùHº2 l»Ÿnhå/¾èÛÀ/ ½'ǹ`So¸.ÜýÕ ÆÛÌ¿ýÛ>»!—¯ÿõ\×÷Q#ñ d¸é&øíƒ§ñLëŒõ\ Ã”šõ¨B?³yKC0hωN- þÍVÖ›•ì¾jš.-Ž@ëC~¥¾¶ÕÇï½mµµ01þg¿¢«»cª0cs¬½—Ï|îÜvË{i^ o}Ëýfž©Æ35¾ÖPºÏkÂñPž#­¦q ›Ñ‘eíÚÕEõNŽä22³Ù%l’ž§7}¸ŒùÜ{ô(ÜrK?ÿñÓvÚ U’µkë)‹øO&AL1zÙñ™+šç©‡H(É%Û}¯!„­[·ÐÒÖŠ˜œ:R`é­„‚LMBu5\vY–Õ‹çsøý´gô¹_Ê Vè\È4›ÛÕ)‘Qkç]žç‚†UädÃb© ëØ|á Gyê©4Bž$ÏÒß?‰ëUâÉfÄTŸ85&íÀ_úRW½ :;áox#‡£8™B!¸d{Z æÜ”…¸9m rÙebå–óñã`L…Ä(¥"°ZhË®Á ¸D£¾u\Yßþv+ž7û£@«(J]4“½±z-²YS0¯Ì_£dFPYªkb9ÄRЦå`×§úûÙжŽP,=Ð,¨×9±|øaÿ³ÑÖA™‚ä‰Åb¢oº[AMçÂM°cÄb º<ñdƒƒ—²z ¼êUA.¼ Èá#x¦‘hü×A«!ÚÚ²¼îu¾ZI¤àÑÇzñLÅœê|²ù¥Zv(YŒ…'~±Û¾“q¾û½Ý8ÙU¹ßóm%”‡çyh`l¬Ç™ãÊå Ð…%ª ñ( û4 ­­ma0d*>@8 ±ò0£cî,‘çú¯3ú,dVbŒ‡™¦¹¬džvW{Dcp5§³ ¬2Nô¹ÿ~øÀ‡¡¾þäÆKøøÇï$•¾ÈOÎË”'ä‹_¼š5kýÅøè£°ï™SˆyÙ,'/ç) ø‹.=ñ › 1xÊ/Ÿõ¶nÆF5ÆT€ Íx –J€Êä•d³m ¤äQ R*)H¹T”ûëtjjjkÐÚ7ªì‚¹ŸB« ¥2h+Žm!æ´ÿŽw m£u‘B1:[‹$ƒe°NƒLùz\ëôcÙýØö lûÊêIÌ«… ®iâ{ßï À—o~3|å˯§®¶“@à»Ûî²  ¡¡¯}íµ¼éMþ3F†áo¿¹‡L¶:_¶rãóP*‰e ⺽31Q`Y#h=$}b(ƒRl+Öc~¢e(=ŒÖ“8n˜ûïãú‹ñO?÷!„,˜"å@H!ËG>ò;üÙ®aË–­yÆ¡ž‘-BYCXÖJeJ)+[ĺÎã8JüHL´,x~+Ç‘”ŽSW“ ¢r”UMå ÑZ[&€¡¡r&&ìwitŽ‹E´5AsÓå壔W$*Ba¸`Sšññ“ˆÄ1"ƒÃÄʧ¢ ÀÄ3U8æ+_æߨ£¬ >þ1Íö¯æöŸåÀ¾!OÑØ\ÉÖ­ ¼óúKÙ±ÓŸ¬D¾ô¥4O<ÂxuyêCÐÚ%§©i˜ææ8¶íK§šêÖ¯Ÿ"O308Žq«QÊBé)jj“TWÇ©©Ê`é±òÚ&àôp9?ýé~ÞýìRøÀAd;7ÿÛ>zN¤Ñ6nŒñþ÷ïäïòÅzuMŸù£8N$')|ùÙÒ¡¡~D¢Ÿ‰Éf\ÇΓ¬ ´[å´ÕÜb1"aúúÕ¯~…ˆH6dDë¤hû„üÕ—EzûDD&'EÆ&DúEº{DÞû^m ‰R)#*w¡\‰ÅNÉÞ!ÒÛ+2<$2>!22"r¢W¤»[¤«K¤³ÓÎð°ÿìÝO‰ÔÖ?(Úe I(üˆ¼ÿƒƒÒÑ.’J‰$S"‰¤H¿Hg‡ÈÀ)ÿ}*íÿ¿«SäÃê‘Pph5) gf<(G”ž”]¯9tÄïר¸ÿ»§EzzD~ø#‘p¤C”ž¥§DÙ]ò坸¿w:7†¡a‘Á‘oÿ­ˆmŸ;Ð.W½êiÙûŒß—DR¤£Cä7¿yà‘'D’ ‘DBä¿Ùxᣢ퓂“@ð€|ûÛþÿGN‹<ö¨È(R^>$(7¯ïF”5,¡Ðcò¿þU$¹óÎ;‹ÖÖ,àäé•`YPQ•EŒ‡¿Ãǵx‹úqàd·?®ƒ…ÂÞ¡,‘(8È&}q ÚAŽë[¨Ù ˆW@ˆâ8òã r`œ°×^ ÍMPYáÍŸvO ÀƒÂM7u±ÿ@Ï]ç»'ùç]`ñ°lˆ•A(ìljUÎ⎕û>¿b–C,„`"e¹ñ§|0(õ‹õûVnO<&¼ûÝí|î³ù/×@CƒïµLc pË­pÓMÏ2:ÞŒx5(4žWÏO~2Åÿk9kÖ¶‹ü¹Òóì#ÏP[ãów)N. ò4,¦TÄBh•@”äÜ3?%Wó/ß?Í=÷L‚ Ïú@J0¦ãí±KrnË:Ÿû“.ÊË'ü´ÌœÜ-S`i©&™¨'™*G‚ aa¼Ïì›à3Ÿyšõ-Y.¾¸†æÕålƒ“N &Ù·o„îpœ6ĬöáRô F£”Í¡ƒýüþ{²§óÜÁH5ccu¸nxý3áûÿ<ÄwŽÏ¤?  U”SƒAŒÄ)Ãu[8vl˜OÞðÛ¶EØyI•×úz“<õô}ý!¿ÌráøK"*¢BˆÂPë±E1ƒùèñÊ0”-:· CM•.ÉÉsÍn/ç®[Z'ÐÆøcŸ“š Š¦âúš»èì.iÿíìÄ̈́ȃö¤dVä"›D„2—šDég‰–ºq)Øh‘èZ~zP~Ð!—•*¥òËg2‡ J Á\žÜâ¨;‹Å˜˜˜åŸ¥qò ˜Å-ôâ÷ÙÙePøüâµ$Í’TjÉðÕÙØÕ±ð3ŠÏ‰©—Rk wNMz”——‡"WVV2<<|m6 --ÐÔh£gœð¢Ô%7HÈ,κp‡eQÄPŠMÒ¼½W‹•É&¾ …Ï»ŽÅb¸®ahpmÃæ—5€dΈxÂ2ׯÒfrÞÞ¦EÅó¸Ð‘½ËNŽŸá<µð‚“üì•…añ=Z…‡­5ûÉÿN’X,Vp„ƒãäél¿¡á~´†;š@§r¸­œ ª­´3µK”•fÇ% ¤’ d ƒÅK!Ï­#FñL KÃÎK¡²ÂB‘¥ØŽ†•ö<uKÉL(µsݼâ^=wàc¦î—ò°­ ®»®•W¾ÒßvâDwÑÝ‹ ¹ø‰Ýù+$ ±zõjŽíP¶ þƒ&båÉBÝ<'ð©òuÊŠ‘¶tLKåÓCP*M(8ÁG?ÚJÀ†cÇ:Tss3¥R}Θ“¶lÙB'Fàâíðö·_‚e,¨›W„öº ÌF [rÝu›ÙµËÏ0êïëfË–-Ëz®^ê c@€¦¦Ut´S–†O~,@MM/–šXDÅè%æ\ÿ¯‰s‚pv·‡¥¦(uñ©ÿ^‰mCGÇ1ÕÔ¼ªdQ¶çÌÉÓÜÜÝÝŽxÙËà¿}x–5â‹meV ®³è6)•AY#¼û=³óR_÷ôt±e˦e?®¤N.ÅÍ«W¯åèÑ£*`Ã'?QNë e£p1sVæŠvfbÛ/ÕÜäð©?nÀ¶áØÑ㪹¹™@ 3l—N·eËÑ-[¶Ðß×M*“¦~|î3Û°­.´• TZéJ[аÎ÷‹ìüÑídýzHg²ô÷ÏêâåJL½œS?lËf˦ÍìÙó”²4\ÿNø×”¡ÔXñSeJ®V³Ÿ.Á ZO²c§áÃà‡÷îyJmÞ|a.ûcšƒ—N·%Ý5×ï]·~=ŽãpúôÔ†p>ÿg;(+@©Ñœµ-+\|Mk­G {ùÂç/§< §ã×:N†õëן91»YÍË]¹÷&wåmf3ÆÌü=66ÆÝwýÏIgDþò/EB¡ÇDëa/w™•kI——+×1,¡Ðò¹Ïº’Έx®ÈÝwý†ñѱ¢4X꥗ÃÔùº ªªŠºú*>¨l þû§àU¯®ÈáÚéä ¬iËâU¯*çÆÏ[Ø>rPÕ×UQYU|#ÛºPº8äU¢]|ñÅôìe|4¹¡<û­—±fMeæv]d…ð”@³(=Nccœo|c 0>žÙpòäI.Ú~ñs×|Ëeý¹×ÄØ8¿úÕ]d3"™¬Èí·‹”W< ÚîTf¶br «×¬\‚rEáˆm HYÙƒòãûsè¸"wÜq'cccÏ™>RâÒ%6ßÊ«¨*ç‚ 6ðÄ“*Ë‚7¾þòKW°zg±íéúœ+È×|×I§Ñº—O}zoû=¿òÒS»ŸT­­ë©ªªZâ™’gÙO.Ö6nl Ç»TÀ†nÐ|ðCÛ±ín´šbed)=œÀ¶Nð–·®ç _¨Æ¶¡³³G9NfÙøô9"ò¬Ÿ&"ìÚµ‹®îvFG'•mÁW¿âu×h‹ Eôñ‹EGŸ‹~*ƒÁ²†xù¥q¾ýwõ„‚01ßÐ~ü»víš­´PÒ4Z:âud¾7cÚOrçwq‘ö‘K¶Ûæé£…Ž>«ýô]%¥b['eýúݲw¯ˆãˆ$“~E½i=lr×Âóî-‰FgE±ç_ýýýüúžûÉf}#âá‡Dï+pòìU审Á¥í>©¨¼[~ö3'#bŒÈý÷=DWW×Y§Ç9!²ˆpôèQxà\O$“¹åV‘ªê‡DÛ'}Ž>Ä~ÑÙˆ‹¶$þ­üÃÿI§EŒ+òäãO°oß¾sB‹sFdaÏž=ì~j&GèÛ~"ÒÐøkÑö QÚý?ϵR®h»OÊ¢¿–o|ÃG ]OäÉÝÏðÔSO3:œS"‹?ü0ô9:-ò³Ÿ‹¬^ûdNGOÎø%Ld¥=QzJ´}R**–ÿï»~_Ç9xø=ôÐs‚,ŸW"3<Ïãþûïgÿ£3}ÏÝ"--÷Šh/KÎ71¦K6Ÿu£ÍmŸú†{å?˜åà£G{¸ï·÷ãoëNäiB?ôÐCìÛ—ÝY‘‡¹èâb‹²FåœwbŸU"礓ÒãbÚ¥µõiùÅ/}O䨱cÜ{ßoȺμy;Ü|Έ[½òE÷ž§÷û„vDŽù/Wï•@ð@Îs ']‰(%E&Ññ/-gÇð:u¡”,¼(”#J¥$8,;w>*O<é/n×yvßaî»ï>Ç9§Ü›©çš#-ËÈyüñÇصëâypzþøÓCüüg'pL“_¼\…fÏl*Näã8rÀX6ä:›B« jkM§îô ¯ym%ßùÇu´¬÷áÊÝO=©\×åŠ+®8ãˆÒy P,÷zæ™=Üÿd2>?9%ò™Ïž–pø·¢í>Q*ñ"4ĦAŽ”hkP¡GäCì’Ó§Dܬˆ“yðGÙ³gÏ93®Î›u]ê:~ü8wß}7ãIqsI7ß,²uëa ŸõÏ›˜GìNBQnޏC”¶Öòÿ)’JЏ®ÈÔdV~óë{9tèÐy™ë³¦“ ²I€áòWqowÝu}½§Û\ÏG~:ÛE>ô¡> GîÛê›5ÈÔ&ûyówó@˜iëÙpøAyÛï¶Ë¾}9ýëŠôõ\s×]÷pòäÉçK>×ï=¯D–9÷NŒsÏ=÷°oß~Äø“J‰ü뿊\¸iŸ‚|®.b˜?Pcúš)ÑÖ€‡eíÚÝò÷'ŸòU‘qÏ=÷0::zÖˆu¦ßSç|sÚ"–™çyìÞ½›T*Ã%—¼B**Bxº{àþ~€ûÿ‘J­ÁóVèyV£L ^ùާ«ä+ÀÒ#ìNÞùÎV>ý©¶lõ«tZxꩇU `±k×®‚3KÇåÏZÔ·øÎ7‘§[OOGŽaݺulÞ¼EŒ×õýùÖ·úùío{ñ¼z<©ÉÒ¦Ÿ'"û‡_+•Bë8–5Èå—ÕñéO·ð¦7‚mAGG»êèè ­­ .¸`IF¯Rò ò2šëº<ñÄ8ŽÇöí—IEe1þÙP·Üÿï?<¡ÃŒ·ãV玩_l…/f^´¢¼äßï¡PÓ'ÛM°úhi‰ó‰O¾Š¼ß?pÛ¶`d,ÉÁ{•¶ ;wî$òBjê…¸—¸««‹öövV­ZŶmÛD¡q<‚[7ß|œÃ&ð¼ZŒ”ûÇù˜ðÌ1Eg$N 䲇&í§æ¨),=Jk[˜÷½w+ïx¬o€ ™l–žU###lÞ¼y^nô ‘!‡ñ<öîÝËèè(­-¶mÜØÒá‰:ÚÔ$üôgðƒ›ŸáÉ'¦pÝ5xn-åLÒÖÔ\@C¥°ô¶u’mYüþ{/åo·¨oðOsÓŽiWÝ=ÇY»v-[¶lY‚î]!rIžçСC$“IZ[[¿Öº¡íOEž ©ÜyÜzë?ÞËØˆÆ£,wèWE#Vî©i88 29}›@©$åå»._Ãï½­7¿Õ?­<`ÒÐÞÞþõîîîËË˹袋(›>ò´¤ÎU+D^jáðáäÓIšš[®ÙtÁ…¿VÄø0IWÜuÇ¿ÜÏ“»‡H¥ñ¼zÄT䌴ùÙRÓ§ÈZú4Á`?—ì¨æº7n濾!Ê˶øû”ö®?~ü¸êè!‰°yófjkk_<9ƒ/8N^dõOLŒqäȦ¦Ô××sÁ$RÃÿO7 {ö½÷ÀÝ÷žàÀA2™0bl¥T.±0CÀN³eS-×^ÛÆÕ×Â+vA0ìWkH¥’?~\>}šŠŠ 6oÞ¼`]é"Ÿeâ'“IŽ=ÊÈÈ‘H”Õ«[eÍêFŸóŒ/ö,<»v?‘aÿS<ØE6ã°mÛ¶m]Å¥—Gٹʢ¾3}h÷ÀÀÝ=ÇU"á—QÚ´iÓ‚by…ÈσÛ588Hww7©TŠªª*Ö¯_/õõõHÎPãïÔÏdü÷‘Ȭ(¶rR|xd˜¾¾¾ ç‡:ƒÁ ëZÖ3½éûÅÞÔK©S"‘ ¯o€þþ~D<Âá2V¯n•X´šê*ŸX&' &ƳÄããô÷woÈdRÆêëkY³fUUU¼”šz©ÖÜš˜˜`rr’ÞÞ^²Ù,JüRU¢ ™Üé•Á`˜5kÖP^^žw,íKo+Ï —ÈËÉFX‚Ÿ˜˜ ™Lþñ /Fj…Èσeÿbm/\Ù¤–Fàb»þŠ/ÜÅ÷-…Àgc—áóÝþ7{ƒ ä`îÌ4IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_eclipse.gif0000644000175000017500000000054412533641120020702 0ustar benbenGIF89aÕ1òª¯í§¯òõûäìù{tO꤮ðõûÞèø‡zL{sPö¬°ƒwM¬Œ@{tPíòú즯—‚FtNóöûêðù}J…E‘H§‹BzsOÚ½|¢ˆCÔ²h{sOàÈæîùçîùðôûÕ²i°>ô«°ö­°Ô²iô¬°ßéøáêøùúüõøû÷ùûþÜç÷þ´=ÿÿÿ!ù1,À˜pH,aÈ$Ò(„©žPŒ9bY¯Ñ´ÈXy¿Ì†Q¼…¢t–\ŠƒôªŸ !M±â¼€E-ˆ‰-E/ ’Eu/›E)¥§¥)E ((®°¯ E.·¸¸E ¾¿ LÆCA;umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo16.png0000644000175000017500000000117412533641120020404 0ustar benben‰PNG  IHDRhôÏ÷bKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ()àÔA IDAT8ËÅ’=hSa†Ÿó}÷öÞ´i,E«£Å*”ºøŠT¤]Z ‚NºˆAt‹¸8J!âк‰ƒvqsQñŠƒPA:ùÓŸÄ6ICÚ›Üûµ±H·‚ÏvÎË ïù&ñÙ‘‘Z¥Y Ìh϶‚ @C¤’X;‘ÀC ©Ô>ʺÔy‘ˆ(€õå3§¾6\ÒZåÞæ42æû?ÖB:Ý_ ëüé1åí'¼»×ÇMV·T3™•ù7û™:yGN«˜ò0ÚC¨ ÚK –1µº»ô«bªi67¯ðò•Ï ‡sÈ73ìë›# iX³§a»c‰·Nïµ/æ^ÚíŽÇmçeüQ÷À‰ é¤áô-M­%•jêØ EÓœZ+ô¡=Ù¶Áí§Ÿ€ïݹ'ÇP¨DÀ÷zzržHÁ³¬²×Õ]ðª1ÚtYàÓ4Jøºj÷iZ³§ E*À”¬Bê ¢Õ÷Œ¯\×W$•ëTT[2¯b±’Ú·Ñ" ¶tX ¡!u[ýWÓ\Üjä’iN¯ü±£#µ-—+J½Ñj ©Éú¢\µÔ‹?ÒÕ“þþp¦½ýÜL29tûX¯õ×…ý H%¸)T[IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/umlet_logo24.png0000644000175000017500000000166312533641120020406 0ustar benben‰PNG  IHDR—p nbKGDÿÿÿ ½§“ pHYs  šœtIMEÝ )"¯,Ö@IDATHÇÝU=lEþÞÌîÝíì®/ø;Îv"DˆDvá†&‰@I—t&RÀ©H… и £C4”œ@4tPPð# J‘ ,ÿÄØñÙÎýìíÞÎGá»Ãgâ šðIOÚùæÍ›7ß{ìÇõBáLKÄZ"M a/e)ôßÄ?âÏ›Nå¯uØ1@fΟŸÃScCȸÛxÿ½¡}~‹Å—ph¤"q¢d«gÐ<àÛ²t¡Â7¦~%òÒ¥ÛÈÖ†ç]Ž´þ¥Ç݇yügˆ•¢ØIª®Ó´-ÀßóGŽv3%Òx¯íq%פK"@P¯)*§Ñ*Pd•PLPV&øÔ,ºÇæÖe€È0küÏŒçaŒ_6×ûwC Ä8µ ʦ'¤ï††| á®í†ÓÔzb¥*©S‘xÍ3Ü•¸hÌ£ƒÖ·™(•X€±Ú¯ò60‘ÞÉÙ°oœË÷•ö^Ü'ÈÙᨥ7SˆµhËKèD*XÒzãe6,/¿¶Éãà ßz{…@ÄññˆSWVØ®)gíLP6§ …RàM3zÍó?7&(ÏÿÒ”u)p6[Ü2AÙþǺoÍq~²—‚àjg,QÊZ¿yD³¼ýëƒàdCëߨM2ØîK=ÿ5×YY3Þè}9¯:ζ›(e·²Ù‹?‹ùïOŒV2™WšJEÍZß<”sfÔ jZȇpåžüQo’¤#/S?€bÇ:å°käÅ wè5ž:Õb©´Àü‘;|çÚˆ“¯Öº¥ñìs¾ðâ˜ÓÓ;=eXjgõœˆ4Ïø€PBÔC2V@‚†ê )" dÀBÄ€ˆ¡˜ºyI}ËJ\l#Üænigµ³ñüß‹ ð_ßÓP¹øOÜ-=«žw&i¿ )ÀùþþÉCÝÃ|>ÖTªÊ=j©».ë¹ì5Ï›ih]íˆ`·É©Ê\Øwú¾¥úãðpXÉd¦ª®{«óŠY€‰R¬9Îìf.wõ›bÑÃÿû8¨LŸèþIEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo20.png0000644000175000017500000000154112533641120020732 0ustar benben‰PNG  IHDR‰ bKGDÿÿÿ ½§“ pHYs  šœtIMEÝ &Û†L¤îIDAT8Ë¥TKhY=õëêîÄNüuÚØ?4‰‰£ˆ"(³É&~íFq'èB7*ãÞ•¨ % nf¡c㇈Ùè"šY FhS]Ý]Ÿ®ª®®ã"&5šÄî»ÜwÞ=—˾ÂtŠª56VG2öŠ ß$Ÿ¬ðÈÙGÖûdKF/“ò2ê’‹ì±L2oÙ"¦Až Jmm'Õk×NéõõvÍšµÁ2E ?J¡þ~5’Ë©v<îøÞÁ%‹ËeÛ‹ƒÿÊòÈH…tæÌ_OɈýç–€Äà'ycß^߸}»ÃûZ0Wº ½½Ç¦,“Tß^ºž–ÓGYÆœáûÞŒ7“¼$ñâåçj$ë.gÝâÉó$=&ë´¡Æ%ž+1IˆJGéд OŸ}}•h?WDV÷Q4Ãe «WGñÏÐÙà"Q "auéðpAPGG1  ]W1ôJB(ÈdD¤Ó.ît‡pñÂBÄb>\ˆ®в"Z[uÜúÛÆÖ-ö´”a˜!aô]%@TÃ@¢.YÂðH5´q»vYpÝq¤8|ØÀóJÔ®,AÓü±"@ÓfàþýƒÿyPBUƒ‰™vwçvTTºL¥òT”+M64è\°ÀaôÝ+{öÆÜm—ÙÞ^x?]gê§hmõN+Š;'«Ë—»ljbóŒ]]f¯(¹³ê.2Ù×guÌ(62ì pòT¶?ù¹hU•Ã+W ]³²ARº×cwÄkt~?S²¡!ËgÏܶYÏÅ2Ë„°·ÿø ýéÎkk‹Ü½ÛäÙ³zéo÷~‘Ðs7¯ŒeœæeKo$…_Ýùúè1"´x.IEND®B`‚umlet-2015-06-03_UMLet_v13.3/Baselet/img/plotlet_logo16.png0000644000175000017500000000121412533641120020734 0ustar benben‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÝ & PAkIDAT8Ë•KKTÇwæÞ‹Ñ°AKÍi¦š@kQd‰…B´é%´tQ­Zùj‘P[Ú¸ð E‹Üªa (¤è¤`ô_£sïÜçÜ9-²¡"múÁŸ‡ó?/Ø£°“»ä‰$¦Dj×Dù"í¹©©›H2#R7+ñDNY¹íN~A°Òéó’L¾óUs‰R,â/-ÙÙÁFiM&QPðWW xÖ絎šÖØÇróÖí7RªDªæ›ýýcå ¤`D³_·/^…ƒ Vƒª†å\:½ñ ÖmGÀðD«rö¢-ŠêøÅ=Yùé÷_.¨‹‹ÕGÛb% šU†‡UR©ë.=WÂävrÛ0=ÝÀúºO<®09 ÍÏéGÔÍÍ’˜†F¬-ÂØX@K‹®ûŒ¿m ¶ÆÅ²"LLÂà M6kbšuŒWñ5«ýøÁ‰“Šèºðì™P Â$â##õtw[ŒŽÖq¡³@HQyñ umlet-2015-06-03_UMLet_v13.3/Baselet/launcher/0000755000175000017500000000000012533641120016403 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/launcher/Umlet Batch Conversion.launch0000644000175000017500000000153312533641120023777 0ustar benben umlet-2015-06-03_UMLet_v13.3/Baselet/launcher/Umlet Standalone.launch0000644000175000017500000000347612533641120022750 0ustar benben ././@LongLink0000644000000000000000000000025300000000000011603 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/Baselet/launcher/Umlet Eclipse Plugin (remove BaseletElement project dependency and link its source folder to make this launcher work).launchumlet-2015-06-03_UMLet_v13.3/Baselet/launcher/Umlet Eclipse Plugin (remove BaseletElement project de0000644000175000017500000000401612533641120030401 0ustar benben umlet-2015-06-03_UMLet_v13.3/Baselet/test/0000755000175000017500000000000012533641120015561 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/test/com/0000755000175000017500000000000012533641120016337 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/test/com/baselet/0000755000175000017500000000000012533641120017756 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/test/com/baselet/MainTest.java0000644000175000017500000000027012533641120022344 0ustar benbenpackage com.baselet; import static org.junit.Assert.assertEquals; import org.junit.Test; public class MainTest { @Test public void dummyTest() { assertEquals(true, true); } } umlet-2015-06-03_UMLet_v13.3/Baselet/.project0000644000175000017500000000123412533641120016251 0ustar benben Baselet org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature umlet-2015-06-03_UMLet_v13.3/Baselet/LICENCE.txt0000644000175000017500000010451312533641120016411 0ustar benben GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . umlet-2015-06-03_UMLet_v13.3/Baselet/html/0000755000175000017500000000000012533641120015546 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/html/about.html.generic0000644000175000017500000000136712533641120021170 0ustar benben

*******************************************

*******************************************


umlet-2015-06-03_UMLet_v13.3/Baselet/html/about.html0000644000175000017500000000132512533641120017547 0ustar benben

*******************************************

UMLet version 13.3
June 2015

Released under the terms of the
GNU General Public License

Web: http://www.umlet.com
Contact: info@umlet.com

*******************************************


umlet-2015-06-03_UMLet_v13.3/Baselet/html/startuphelp.html0000644000175000017500000000243012533641120021006 0ustar benben

UMLet 13.3 -- check for new versions -- read the FAQ


Double-click on an element to add it to the diagram (or use drag&drop)
Use Ctrl+Space in text panel to get context-sensitive help
Use the "layer=" command to move elements to front/to back
Lasso with Ctrl+Mouse -- zoom with Ctrl+MouseWheel
Let UMLet generate diagrams from your source code or class files in the file menu..
Advanced: "Custom Elements > New..." lets you create entirely new element types

If you like UMLet, please "star" it at Eclipse Marketplace. We really appreciate it!

umlet-2015-06-03_UMLet_v13.3/Baselet/html/startuphelp.html.generic0000644000175000017500000000244512533641120022427 0ustar benben

UMLet @release.version@ -- check for new versions -- read the FAQ


Double-click on an element to add it to the diagram (or use drag&drop)
Use Ctrl+Space in text panel to get context-sensitive help
Use the "layer=" command to move elements to front/to back
Lasso with Ctrl+Mouse -- zoom with Ctrl+MouseWheel
Let UMLet generate diagrams from your source code or class files in the file menu..
Advanced: "Custom Elements > New..." lets you create entirely new element types

If you like UMLet, please "star" it at Eclipse Marketplace. We really appreciate it!

umlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/0000755000175000017500000000000012533641120020010 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/WordWrap.java0000644000175000017500000000144512533641120022424 0ustar benbenimport java.awt.*; import java.util.*; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.element.old.custom.CustomElement; @SuppressWarnings("serial") public class extends CustomElement { public CustomElementImpl() { } @Override public void paint() { Vector textlines = Utils.decomposeStrings(this.getPanelAttributes()); /****CUSTOM_CODE START****/ //This is an element with activated wordwrap //If a line would exceed the elements border, instead //the exceeding part is written into the next line int y=textHeight(); drawRectangle(0,0,width,height); setWordWrap(true); for(String textline : textlines) { y += printCenter(textline,y); } /****CUSTOM_CODE END****/ } } umlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/AutoResize1.java0000644000175000017500000000151612533641120023031 0ustar benbenimport java.awt.*; import java.util.*; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.element.old.custom.CustomElement; @SuppressWarnings("serial") public class extends CustomElement { public CustomElementImpl() { } @Override public void paint() { Vector textlines = Utils.decomposeStrings(this.getPanelAttributes()); /****CUSTOM_CODE START****/ //This is a tutorial for a self resizing component //In addition you are able to resize at manually //As soon as it is resized manually a new text is //added to the property panel allowResize(false); setAutoresize(30,40,10); drawCircle(width/2,15,10); int y=45; for(String textline : textlines) { y += printCenter(textline,y); } /****CUSTOM_CODE END****/ } } umlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/AutoResize2.java0000644000175000017500000000224112533641120023026 0ustar benbenimport java.awt.*; import java.util.*; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.element.old.custom.CustomElement; @SuppressWarnings("serial") public class extends CustomElement { public CustomElementImpl() { } @Override public void paint() { Vector textlines = Utils.decomposeStrings(this.getPanelAttributes()); /****CUSTOM_CODE START****/ //This is a tutorial for a self resizing component //In addition you are able to resize at manually //As soon as it is resized manually a new text is //added to the property panel setAutoresize(20,20,10); int y=textHeight(); boolean center = true; for(int i = 0; i < textlines.size(); i++) { String textline = textlines.get(i); if(textline.equals("--")) { drawLineHorizontal((int) (y-textHeight()*0.7)); center = false; if (!isManualResized()) height -= (int) (textHeight()*0.75); y += textHeight()*0.3; } else { if (center) y += printCenter(textline,y); else y += printLeft(textline,y); } } drawRectangle(0,0,onGrid(width),onGrid(height)); /****CUSTOM_CODE END****/ } }umlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/RectangleRound.java0000644000175000017500000000117712533641120023575 0ustar benbenimport java.awt.*; import java.util.*; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.element.old.custom.CustomElement; @SuppressWarnings("serial") public class extends CustomElement { public CustomElementImpl() { } @Override public void paint() { Vector textlines = Utils.decomposeStrings(this.getPanelAttributes()); /****CUSTOM_CODE START****/ int y=textHeight(); drawRectangleRound(0,0,width,height,20,20); for(String textline : textlines) { y += printCenter(textline,y); } /****CUSTOM_CODE END****/ } }umlet-2015-06-03_UMLet_v13.3/Baselet/custom_elements/Default.java0000644000175000017500000000150412533641120022237 0ustar benbenimport java.awt.*; import java.util.*; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.element.old.custom.CustomElement; @SuppressWarnings("serial") public class extends CustomElement { public CustomElementImpl() { } @Override public void paint() { Vector textlines = Utils.decomposeStrings(this.getPanelAttributes()); /****CUSTOM_CODE START****/ //Modify the code below to define the element's behavior. // //Example: Change the line // y += printCenter(textline,y); //to // y += 2*printCenter(textline,y); //and observe the element preview. int y=textHeight(); drawRectangle(0,0,width,height); for(String textline : textlines) { y += printCenter(textline,y); } /****CUSTOM_CODE END****/ } }umlet-2015-06-03_UMLet_v13.3/Baselet/lib/0000755000175000017500000000000012537353206015361 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/lib/libinfo.txt0000644000175000017500000000216612533641120017540 0ustar benben batik* Licence: Apache License 2.0 Used for: Export to "eps" and "svg" jlibeps Licence: GPL2+ Used for: Export to "eps" and "svg" iText Licence: AGPL Used for: Export to "pdf" JavaMail (mailapi.jar, smtp.jar) Licence: GPLv2 with "GPL linking exception" Used for: Sending mails from Umlet/Plotlet log4j Licence: Apache License 2.0 Used for: Logging RSyntaxTextArea + Autocomplete Locence: modified BSD (http://fifesoft.com/rsyntaxtextarea/RSyntaxTextArea.License.txt) Used for: TextArea with syntax highlighting and autocompletion (replacement for jsyntaxpane) URL: http://fifesoft.com/rsyntaxtextarea/ http://fifesoft.com/autocomplete/ Apache Commons Bcel (bcel.jar) Licence: Apache License 2.0 Used for: Class diagram generation Javaparser Licence: LGPL Used for: Parsing java classes for class diagrams generation Apache Commons IO Licence: Apache Licence 2.0 Used for: Reading wildcard input files in batch mode Eclipse JDT Core Batch Compiler Licence: Eclipse Public Licence Used for: Compiling custom elements in Umlet Maven: http://mvnrepository.com/artifact/org.eclipse.jdt.core.compiler/ecj/4.3.1umlet-2015-06-03_UMLet_v13.3/Baselet/.classpath0000644000175000017500000000277212533641120016575 0ustar benben umlet-2015-06-03_UMLet_v13.3/Baselet/log4j.properties0000644000175000017500000000264612533641120017747 0ustar benben # Logger setup for all loggers (all loggers inherit from rootLogger) log4j.rootLogger=INFO, SYSTEM_OUT, FILE # Appender SYSTEM_OUT writes to the console log4j.appender.SYSTEM_OUT=org.apache.log4j.ConsoleAppender log4j.appender.SYSTEM_OUT.layout=org.apache.log4j.PatternLayout log4j.appender.SYSTEM_OUT.layout.ConversionPattern=%d{ISO8601} | %6r | %-5p | %-30c | %m%n # Appender FILE writes to the file "log4j.log". log4j.appender.FILE=org.apache.log4j.FileAppender log4j.appender.FILE.File=${PROJECT_PATH}/log4j.log log4j.appender.FILE.Append=true log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{ISO8601} | %6r | %-5p | %-30c | %m%n # Appender SYSTEM_OUT_SLOW writes to the console and links to the exact calling method (This is SLOW!) log4j.appender.SYSTEM_OUT_SLOW=org.apache.log4j.ConsoleAppender log4j.appender.SYSTEM_OUT_SLOW.layout=org.apache.log4j.PatternLayout log4j.appender.SYSTEM_OUT_SLOW.layout.ConversionPattern=%6r | %-5p | %-60l - "%m"%n # Individual activation/deactivation of loggers # use log4j.logger(.PACKAGE)+(.CLASSNAME)? -> eg: log4j.logger.main.control.Main=INFO log4j.logger.com.baselet.elementnew.facet.relation.RelationLineTypeFacet=INFO log4j.logger.com.baselet.control.DiagramHandler=INFO log4j.logger.com.baselet.diagram.draw.PlotDrawHandler=DEBUG log4j.logger.com.baselet.diagram.draw.geom=DEBUG log4j.logger.com.baselet.elementnew.NewGridElement=DEBUGumlet-2015-06-03_UMLet_v13.3/Baselet/palettes/0000755000175000017500000000000012533641120016423 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Composite Structure.uxf0000644000175000017500000000742312533641120023516 0ustar benben 8 UMLGeneric 16 16 160 80 symbol=component Component UMLGeneric 16 176 160 88 symbol=component Component UMLGeneric 16 384 160 48 symbol=component Component Relation 168 56 56 184 lt=[>]-[>] 10.0;10.0;50.0;10.0;50.0;210.0;10.0;210.0 Relation 80 88 24 104 lt=[^]-[v] 10.0;10.0;10.0;110.0 Relation 56 88 24 104 lt=[=]-[<] 10.0;10.0;10.0;110.0 Relation 24 88 40 104 lt=[GUI]-[SQL] 20.0;10.0;20.0;110.0 Relation 96 88 40 64 lt=[v]-( 20.0;10.0;20.0;50.0 Relation 104 136 24 56 lt=()-[v] 10.0;10.0;10.0;50.0 Relation 56 256 80 96 lt=[].> m2=<<delegate>> 60.0;10.0;10.0;60.0;10.0;100.0 Relation 56 336 24 64 lt=()- 10.0;10.0;10.0;60.0 Relation 104 264 104 88 lt=<. m2=<<delegate>> 10.0;10.0;40.0;50.0;40.0;90.0 Relation 120 336 40 64 lt=)- 20.0;20.0;20.0;60.0 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Use Case.uxf0000644000175000017500000001031312533641120021153 0ustar benben 8 UMLUseCase 8 176 128 72 Use Case -- extension points valign=top UMLUseCase 16 16 96 32 Use case 1 UMLNote 152 176 104 56 Note.. bg=blue UMLActor 120 16 48 80 Actor UMLGeneric 112 256 144 56 Alt. Use Case -- extension points symbol=usecase Relation 16 152 112 24 lt=->> 10.0;10.0;120.0;10.0 UMLGeneric 176 16 80 80 System halign=left UMLGeneric 152 120 104 32 Neighboursystem valign=center Relation 16 128 104 24 lt=.() 10.0;10.0;110.0;10.0 Relation 16 104 112 32 10.0;20.0;120.0;20.0 Relation 16 96 112 24 lt=.>> 10.0;10.0;120.0;10.0 Relation 16 72 112 32 lt=.> <<extends>> 10.0;20.0;120.0;20.0 Relation 16 48 112 32 lt=.> <<includes>> 10.0;20.0;120.0;20.0 UMLHierarchy 8 320 360 216 type=WorkProcess Workprocess1 Workprocess2 Workprocess3 Workprocess4 Workprocess5 UMLHierarchy 264 16 160 296 type=Actor Actor1 Actor2 Actor3 Actor4 Actor5 Actor6 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML State Machine.uxf0000644000175000017500000000671312533641120022201 0ustar benben 8 UMLSpecialState 56 16 16 16 type=initial UMLSpecialState 104 16 16 16 type=termination UMLSpecialState 32 16 16 16 type=flow_final UMLSpecialState 80 16 16 16 type=final UMLSpecialState 120 80 32 32 type=decision UMLState 24 80 72 32 state UMLState 24 120 144 88 complex state -- some more... -- valign=top UMLState 64 232 80 32 state UMLState 32 304 96 48 state with substates symbol=substate Relation 16 48 152 24 lt=-> 10.0;10.0;170.0;10.0 Relation 24 240 96 64 lt=-> self 100.0;30.0;100.0;60.0;10.0;60.0;10.0;10.0;50.0;10.0 UMLSpecialState 128 16 16 16 type=history_shallow UMLSpecialState 152 16 16 16 type=history_deep umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Class.uxf0000644000175000017500000001750612533641120020643 0ustar benben 8 UMLClass 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long {composite} _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 -- Resp2 UMLClass 16 16 80 24 SimpleClass UMLClass 104 16 80 24 /AbstractClass/ UMLClass 192 16 88 32 type=actclass ActiveClass UMLClass 192 64 88 32 lw=2 ActiveClass UMLClass 192 112 88 32 lt=. Class with dashed border UMLClass 160 208 128 56 template=0: Object TemplateClass -- UMLNote 160 272 112 56 Note.. UMLUseCase 168 336 96 32 lt=. Collaboration UMLClass 288 16 136 104 OuterClass {innerclass InnerClass innerclass} {innerclass InnerClass {innerclass InnerInnerClass -- field innerclass} innerclass} UMLInterface 288 120 64 80 Interface -- Operation1 Operation2 Relation 8 208 152 24 lt=<<- 10.0;10.0;170.0;10.0 Relation 8 224 152 24 lt=<<. 10.0;10.0;170.0;10.0 Relation 8 240 152 24 lt=<- 10.0;10.0;170.0;10.0 Relation 8 256 152 24 lt=<. 10.0;10.0;170.0;10.0 Relation 8 328 152 32 lt=<- m1=0..n 10.0;10.0;170.0;10.0 Relation 8 352 152 24 lt=<<<- 10.0;10.0;170.0;10.0 Relation 8 368 152 24 lt=<<<<- 10.0;10.0;170.0;10.0 Relation 16 384 144 40 lt=[key]-> m2=0..1 m1=0..n 20.0;20.0;160.0;20.0 UMLClass 160 416 48 16 Rose bg=red Relation 184 392 104 48 lt=<<- a rose is a rose 30.0;40.0;70.0;40.0;70.0;10.0;10.0;10.0;10.0;30.0 Relation 16 424 136 40 lt=)- m1=require 20.0;20.0;150.0;20.0 Relation 16 456 128 40 lt=-() m2=provide 10.0;20.0;140.0;20.0 Relation 304 200 88 128 lt=- m1=1 r1=professor m2=1..n r2=student teaches to v 10.0;10.0;10.0;140.0 Relation 304 328 88 120 lt=- m1=0..n m2=1 teaches to ^ 10.0;10.0;10.0;130.0 Relation 8 272 152 40 lt=- m1=0..n m2=0..1 teaches to > 10.0;20.0;170.0;20.0 Relation 8 296 152 40 lt=- m1=3 m2=1 < teaches to 10.0;20.0;170.0;20.0 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Structure and Deployment.uxf0000644000175000017500000000747412533641120026563 0ustar benben 8 com.umlet.element.custom.Node 16 8 88 40 center:Node com.umlet.element.custom.Node 128 8 88 40 center:<<device>> center:Name com.umlet.element.Relation 0 24 218 56 lt=- _Link_ 24;40;208;40 com.umlet.element.custom.Node 16 80 200 64 center:<<execution environment>> center:Name com.umlet.element.custom.Node 16 152 200 64 center:<<Deployment Descriptor>> center:Name com.umlet.element.custom.Component 16 224 104 64 Component com.umlet.element.custom.Artefact 128 224 88 64 Artifact com.umlet.element.Class 16 296 104 32 <<component>> Name com.umlet.element.Class 128 296 88 32 <<artifact>> Name com.umlet.element.custom.SimpleComponent 16 336 152 56 Component com.umlet.element.custom.Database 16 480 88 32 Database com.umlet.element.Class 72 424 88 40 <<artefact>> Name com.umlet.element.custom.Node 16 400 200 72 center:Deployment umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Structure and Deployment.uxf0000644000175000017500000000533312533641120024415 0ustar benben 8 UMLDeployment 16 16 88 40 Node UMLDeployment 16 72 200 64 <<execution environment>> Name UMLDeployment 128 16 88 40 <<device>> Name UMLDeployment 16 144 200 64 <<Deployment Descriptor>> Name UMLGeneric 136 216 88 64 symbol=artifact Artifact UMLGeneric 16 216 112 64 symbol=component Component UMLGeneric 16 288 112 32 <<component>> Name UMLGeneric 136 288 88 32 <<artifact>> Name UMLGeneric 72 352 88 40 <<artefact>> Name group=1 UMLDeployment 16 328 200 72 Deployment group=1 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Plots.uxf0000644000175000017500000001067212533641120020256 0ustar benben // Uncomment the following line to change the fontsize and font: fontsize=10 // fontfamily=SansSerif //possible: SansSerif,Serif,Monospaced ////////////////////////////////////////////////////////////////////////////////////////////// // Welcome to UMLet! // // Double-click on elements to add them to the diagram, or to copy them // Edit elements by modifying the text in this panel // Hold Ctrl to select multiple elements // Use Ctrl+mouse to select via lasso // // Use +/- or Ctrl+mouse wheel to zoom // Drag a whole relation at its central square icon // // Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) // Edit the files in the "palettes" directory to create your own element palettes // // Select "Custom Elements > New..." to create new element types ////////////////////////////////////////////////////////////////////////////////////////////// // This text will be stored with each diagram; use it for notes. 10 PlotGrid 30 230 500 350 // datasets can have optional names set (in this case "first_name") data first_name a b c d 1 3 1 6 data a b c 2 -4 4 // some settings are global, like the width of the grid grid.width=4 // variables which are on the same line as "plot" are only set for this plot plot type=pie colors=red,blue,yellow,#3c7a00 // A variable which is on it's own line is valid for every following plot type=line colors=blue plot plot plot type=scatter plot type=scatter // auto resets the variable to it's default value (in this case "bar") type=auto colors=auto plot // to use the highest/lowest value of all datasets, set value.min/max to all value.min=all value.max=all plot // you can set the data to plot by number plot data=#1 // ... or by name plot data=first_name // a custom min/max value sets a custom range of values for the axis value.min=-6 value.max=10 plot PlotGrid 550 240 500 390 // there are numerous axis configurations which are shown here data a b c -5 7 13 type=line axis.desc.show= axis.value.show= axis.value.list=relevant plot axis.desc.show=axis plot axis.value.show=axis plot axis.desc.show=axis,line plot axis.value.show=axis,line plot axis.desc.show=axis,line,marker plot axis.value.show=axis,line,marker plot axis.desc.show=axis,line,marker,text plot axis.value.show=axis,line,marker,text plot axis.value.list= plot axis.value.list=-8,-1,3.5,17 plot axis.value.list=-8,-1,3.5,17,relevant plot PlotGrid 670 20 190 150 data a b c x -16 5.5 18.3 y 3 5 1 z 5 9 -3 type=scatter axis.value.show=axis axis.desc.show=axis,marker,text plot PlotGrid 220 20 170 130 // single plots are easily created without using capabilities of a (plot)grid data a b c 3 7 13 plot type=bar PlotGrid 20 20 170 130 // single plots are easily created without using capabilities of a (plot)grid data a b c 3 7 13 plot type=pie PlotGrid 450 20 190 150 data a b c x -16 5.5 18.3 y 3 5 1 z 5 9 -3 type=line axis.value.show=axis axis.desc.show=axis,marker,text plot data=#1 data.invert=true ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Common Elements - old element versions.uxfumlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Common Elements - old element version0000644000175000017500000002270012533641120030044 0ustar benben 8 com.umlet.element.Relation 176 128 168 40 lt=<. 24;24;152;24 com.umlet.element.Relation 176 112 168 40 lt=<- 24;24;152;24 com.umlet.element.Relation 176 96 168 40 lt=<<. 24;24;152;24 com.umlet.element.Note 208 336 112 56 Note.. bg=blue com.umlet.element.Relation 176 128 168 56 lt=- m1=0..n m2=0..1 teaches to> 24;40;152;40 com.umlet.element.Package 208 464 112 56 Package 1 -- -Content 1 +Content 2 bg=gray fg=red com.umlet.element.Relation 176 152 172 56 lt=<.> <<someStereotype>> 24;40;152;40 com.umlet.element.Relation 176 184 168 40 lt=<- m1=0..n r1=Role 24;24;152;24 com.umlet.element.Actor 120 408 80 96 Actor com.umlet.element.UseCase 104 328 96 32 *Use case 3* com.umlet.element.Package 208 400 112 56 EmptyPackage bg=orange com.umlet.element.UseCase 16 448 96 32 lt=. Collaboration fg=red bg=yellow com.umlet.element.UseCase 16 304 96 32 Use case 1 com.umlet.element.UseCase 16 376 96 32 Use case 2 bg=blue com.umlet.element.Relation 176 248 168 40 lt=<- q1=Qualification m1=1..5,6,7 24;24;152;24 com.umlet.element.Relation 176 224 168 40 lt=<<<<- 24;24;152;24 com.umlet.element.Relation 176 208 168 40 lt=<<<- 24;24;152;24 com.umlet.element.Class 288 56 48 16 Rose bg=red com.umlet.element.Interface 200 16 64 72 Interface -- Operation1 Operation2 com.umlet.element.Relation 64 336 126 72 lt=<. <<extends>> 48;56;80;24 com.umlet.element.Relation 296 0 130 80 lt=>> a rose is a rose is a rose 24;56;24;40;72;40;72;64;40;64 com.umlet.element.Class 16 240 168 56 _object: Class_ -- id: Long="36548" [waiting for message] com.umlet.element.Relation 24 176 140 80 lt=<. <<instanceOf>> 72;24;72;64 com.umlet.element.Class 104 16 80 24 /AbstractClass/ com.umlet.element.Relation 72 384 80 64 24;24;64;48 com.umlet.element.Class 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 *-- Resp2* com.umlet.element.Class 16 16 80 24 SimpleClass com.umlet.element.Relation 40 384 40 80 lt=<<. 24;24;24;64 com.umlet.element.Relation 0 312 122 80 lt=<. <<include>> 64;24;64;64 com.umlet.element.Relation 176 80 168 40 lt=<<- 24;24;152;24 com.umlet.element.custom.Text 336 168 80 80 This is a text element to place text anywhere. com.umlet.element.Relation 184 280 160 40 lt== 24;24;144;24 com.umlet.element.Relation 184 296 160 40 lt=: 24;24;144;24 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Common Elements.uxf0000644000175000017500000002137512533641120022562 0ustar benben 8 UMLClass 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 *-- Resp2* UMLClass 104 16 80 24 /AbstractClass/ UMLClass 16 240 168 56 _object: Class_ -- id: Long="36548" [waiting for message] UMLClass 288 56 48 16 Rose bg=red UMLUseCase 16 304 96 32 Use case 1 UMLUseCase 104 328 96 32 *Use case 3* UMLUseCase 16 376 96 32 Use case 2 bg=blue UMLUseCase 16 448 96 32 lt=. Collaboration fg=red bg=yellow UMLActor 136 408 48 80 Actor UMLNote 216 304 112 56 Note.. bg=blue UMLPackage 216 376 112 56 EmptyPackage -- bg=orange UMLPackage 216 448 112 56 Package 1 -- -Content 1 +Content 2 bg=gray fg=red UMLInterface 200 8 64 80 Interface -- Operation1 Operation2 UMLClass 16 16 80 24 SimpleClass Text 336 168 80 56 This is a text element to place text anywhere. Relation 192 96 152 24 lt=<<- 10.0;10.0;170.0;10.0 Relation 192 112 152 24 lt=<<. 10.0;10.0;170.0;10.0 Relation 192 128 152 24 lt=<- 10.0;10.0;170.0;10.0 Relation 192 144 152 24 lt=<. 10.0;10.0;170.0;10.0 Relation 192 152 152 40 lt=- m1=0..n m2=0..1 teaches to > 10.0;20.0;170.0;20.0 Relation 192 176 152 32 lt=<.> <<someStereotype>> 10.0;20.0;170.0;20.0 Relation 192 200 152 32 lt=<- m1=0..n 10.0;10.0;170.0;10.0 Relation 192 224 152 24 lt=<<<- 10.0;10.0;170.0;10.0 Relation 192 240 152 24 lt=<<<<- 10.0;10.0;170.0;10.0 Relation 192 264 152 32 lt=[Qualification]<- m2=1..5,6 40.0;10.0;170.0;10.0 Relation 64 192 80 64 lt=<. <<instanceOf>> 40.0;10.0;40.0;60.0 Relation 40 328 56 64 lt=<. <<include>> 30.0;10.0;30.0;60.0 Relation 88 352 64 48 lt=.> <<extends>> 50.0;10.0;20.0;40.0 Relation 56 400 24 64 lt=<<. 10.0;10.0;10.0;60.0 Relation 88 400 72 48 10.0;10.0;70.0;40.0 Relation 312 32 104 48 lt=<<- a rose is a rose 30.0;40.0;70.0;40.0;70.0;10.0;10.0;10.0;10.0;30.0 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Generic Colors.uxf0000644000175000017500000000750512533641120021754 0ustar benben 8 UMLUseCase 8 8 88 32 red bg=red UMLUseCase 8 48 88 32 green bg=green UMLUseCase 8 88 88 32 blue bg=blue UMLUseCase 8 128 88 32 yellow bg=yellow UMLUseCase 112 8 88 32 white bg=white UMLUseCase 112 168 88 32 black bg=black fg=white UMLUseCase 112 88 88 32 gray bg=gray UMLUseCase 112 48 88 32 light_gray bg=light_gray UMLUseCase 112 128 88 32 dark_gray bg=dark_gray UMLUseCase 8 168 88 32 orange bg=orange UMLUseCase 112 208 88 32 pink bg=pink UMLUseCase 8 208 88 32 magenta bg=magenta UMLUseCase 8 248 88 32 cyan bg=cyan UMLUseCase 112 248 88 32 #3c7a00 bg=#3c7a00 UMLUseCase 8 288 88 32 cyan opaque bg=cyan transparency=0 layer=1 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Generic Text and Alignment.uxf0000644000175000017500000001017512533641120024056 0ustar benben 8 UMLClass 16 16 88 96 halign=left Top left bla bla bla UMLClass 120 16 88 96 halign=center Top center bla bla bla UMLClass 224 16 88 96 halign=right Top right bla bla bla UMLClass 16 120 88 96 valign=center halign=left Middle left bla bla bla UMLClass 120 120 88 96 valign=center halign=center Middle center bla bla bla UMLClass 224 120 88 96 valign=center halign=right Middle right bla bla bla UMLClass 16 224 88 96 valign=bottom halign=left Bottom left bla bla bla UMLClass 120 224 88 96 valign=bottom halign=center Bottom center bla bla bla UMLClass 224 224 88 96 valign=bottom halign=right Bottom right bla bla bla UMLClass 16 336 296 104 This class has the setting *style=wordwrap* -- Write text and watch how the linebreak is added automatically at the expected position to fill the whole class. You can also resize the class and see that the text will always fit the border style=wordwrap UMLClass 16 456 296 64 This class has the setting *style=autoresize* -- Write text <here>, and see how the class grows/shrinks.... style=autoresize UMLClass 16 544 112 88 This class has the settings *valign=center* *fontsize=18* *lw=2.5* valign=center fontsize=18 lw=2.5 UMLUseCase 152 544 152 72 this usecase has *halign=left* -- The text is always within the usecase circle halign=LEFT umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Package.uxf0000644000175000017500000000647012533641120021127 0ustar benben 8 UMLPackage 16 80 80 56 Text UMLPackage 16 144 80 56 Name -- Text Text halign=left UMLPackage 152 16 80 56 Name -- Text Text bg=blue UMLPackage 16 16 80 56 Name UMLPackage 152 128 80 56 Name -- Text Text bg=green UMLPackage 40 232 80 56 group=1 UMLPackage 16 208 120 88 group=1 Relation 24 312 120 32 lt=.> <<access>> 10.0;20.0;130.0;20.0 Relation 24 336 120 32 lt=.> <<import>> 10.0;20.0;130.0;20.0 Relation 24 360 120 32 lt=.> <<merge>> 10.0;20.0;130.0;20.0 Relation 184 72 24 88 lt=(+)- 10.0;10.0;10.0;90.0 UMLHierarchy 152 200 136 192 type=Package root name name name name root name umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Use Case.uxf0000644000175000017500000001071312533641120023315 0ustar benben 8 com.umlet.element.Note 152 176 104 56 Note.. bg=blue com.umlet.element.custom.Taxonomy_of_Workprocesses 8 320 360 216 Workprocess1 Workprocess2 Workprocess3 Workprocess4 Workprocess5 com.umlet.element.Relation 0 112 112 40 lt=<(). 96;24;24;24 com.umlet.element.Relation 0 96 128 40 112;24;24;24 com.umlet.element.Relation 0 80 128 40 lt=<<. 112;24;24;24 com.umlet.element.Relation 0 48 128 56 lt=<. <<extends>> 112;40;24;40 com.umlet.element.Relation 0 24 128 56 lt=<. <<includes>> 112;40;24;40 com.umlet.element.custom.Systemborder 152 120 104 32 center:Neighboursystem com.umlet.element.custom.AlternativeUseCase 128 256 128 56 Alt. Use Case -- extension points com.umlet.element.UseCase 8 176 128 72 Use Case -- extension points com.umlet.element.custom.Taxonomy_of_Actors 264 16 160 296 Actor1 Actor2 Actor3 Actor4 Actor5 Actor6 com.umlet.element.custom.Systemborder 176 16 80 80 System com.umlet.element.Actor 112 16 64 96 Actor com.umlet.element.UseCase 16 16 96 32 Use case 1 com.umlet.element.Relation 0 136 128 40 lt=<<- 112;24;24;24 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Class.uxf0000644000175000017500000002012712533641120022772 0ustar benben 8 com.umlet.element.Relation 0 424 152 40 lt=()) 24;24;136;24 com.umlet.element.Relation 0 400 136 40 lt=<() r1=provide 120;24;24;24 com.umlet.element.Relation 8 376 144 40 lt=<( r1=require 24;24;128;24 com.umlet.element.Relation 0 352 152 40 lt=- m1=0..n q1=key m2=0..1 24;24;136;24 com.umlet.element.Relation 0 336 152 40 lt=<x 24;24;136;24 com.umlet.element.Relation 0 320 152 40 lt=<<<- 24;24;136;24 com.umlet.element.Relation 0 304 152 40 lt=<<<<- 24;24;136;24 com.umlet.element.Relation 0 280 152 40 lt=<- m1=0..n r1=Role 24;24;136;24 com.umlet.element.Relation 0 240 152 56 lt=- m1=0..n m2=0..1 teaches to> 24;40;136;40 com.umlet.element.Relation 0 240 152 40 lt=<. 24;24;136;24 com.umlet.element.Relation 0 224 152 40 lt=<- 24;24;136;24 com.umlet.element.Relation 0 208 152 40 lt=<<. 24;24;136;24 com.umlet.element.Relation 0 192 152 40 lt=<<- 24;24;136;24 com.umlet.element.Note 160 272 112 56 Note.. com.umlet.element.UseCase 168 336 96 32 lt=. Collaboration com.umlet.element.Class 160 208 128 56 template=0: Object TemplateClass -- com.umlet.element.Class 160 408 48 16 Rose com.umlet.element.Class 288 16 136 104 OuterClass {innerclass InnerClass innerclass} {innerclass InnerClass {innerclass InnerInnerClass -- field innerclass} innerclass} com.umlet.element.Interface 288 128 64 72 Interface -- Operation1 Operation2 com.umlet.element.custom.ThreeWayRelation 216 160 48 32 com.umlet.element.Relation 168 352 138 80 lt=>> a rose is a rose is a rose 24;56;24;32;80;40;80;64;40;64 com.umlet.element.Class 192 16 88 32 {active} ActiveClass com.umlet.element.Class 104 16 80 24 /AbstractClass/ com.umlet.element.Class 16 48 168 152 <<Stereotype>> Package::FatClass {Some Properties} -- -id: Long {composite} _-ClassAttribute: Long_ -- #Operation(i: int): int /+AbstractOperation()/ -- Responsibilities -- Resp1 -- Resp2 com.umlet.element.Class 16 16 80 24 SimpleClass com.umlet.element.Class 192 64 88 32 bt=* ActiveClass com.umlet.element.Class 192 112 88 32 bt=. Class with dashed border umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Composite Structure.uxf0000644000175000017500000000620412533641120025650 0ustar benben 8 com.umlet.element.Relation 152 40 72 200 lt=<[>] - [>]> 24;24;56;24;56;184;24;184 com.umlet.element.Relation 72 240 114 160 lt=<[]<.)- <<delegate>> 32;24;64;64;64;144 com.umlet.element.Relation 88 72 40 120 lt=<[v]-(()-[^]> 24;24;24;104 com.umlet.element.Relation 64 72 40 120 lt=<[^][v]> 24;24;24;104 com.umlet.element.Relation 40 72 40 120 lt=<[=][<]> 24;24;24;104 com.umlet.element.Relation 16 72 40 120 lt=<[SQL][GUI]> 24;104;24;24 com.umlet.element.custom.Component 16 176 160 88 'Component com.umlet.element.Relation 0 240 120 160 lt=<[].>()- <<delegate>> 104;24;64;64;64;144 com.umlet.element.custom.Component 16 384 160 48 'Component com.umlet.element.custom.Component 16 16 160 80 'Component umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Generic Layers.uxf0000644000175000017500000000334312533641120021746 0ustar benben 10 UMLPackage 30 30 280 260 EmptyPackage -- bg=orange UMLClass 60 80 140 150 SimpleClass bg=blue layer=2 UMLClass 110 110 170 150 Foreground via the "layer" command bg=green layer=3 UMLPackage 30 310 280 260 EmptyPackage -- bg=orange UMLClass 60 360 140 150 SimpleClass bg=blue layer=2 UMLClass 110 390 170 150 Background via the "layer" command bg=white layer=1 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Package.uxf0000644000175000017500000000701712533641120023263 0ustar benben 8 com.umlet.element.Package 152 128 80 56 -- Name bg=green com.umlet.element.Package 152 16 80 56 -- Name bg=blue com.umlet.element.custom.PackageAggregationHierarchy 152 200 136 184 root name name name name root name com.umlet.element.Package 16 80 80 56 -- Name com.umlet.element.Relation 168 48 40 112 lt=<(+)- 24;24;24;96 com.umlet.element.Package 16 144 80 56 Name -- left:Text Text com.umlet.element.Relation 0 336 144 56 lt=<. <<merge>> 128;40;24;40 com.umlet.element.Relation 0 312 144 56 lt=<. <<import>> 128;40;24;40 com.umlet.element.Relation 0 288 144 56 lt=<. <<access>> 128;40;24;40 com.umlet.element.Package 16 16 80 56 Name com.umlet.element.Package 16 208 120 88 com.umlet.element.Package 40 232 80 56 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Activity - All in one.uxf0000644000175000017500000000205512533641120023322 0ustar benben 8 com.umlet.element.ActivityDiagramText 8 8 64 84 title:start Start End com.umlet.element.ActivityDiagramText 104 8 561 656 title:Example Hotline Start Telephone\ rings While[open\calls] [free] Fork If [responsible] take call help caller [not responsible] forward call\(with subactions).. EndIf | | | document call~id1 Sync [busy] record\call wait until\ free> >free playback\recorded cal->id1 [no open calls] End umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Sequence.uxf0000644000175000017500000001632712533641120021346 0ustar benben 8 UMLFrame 16 184 144 56 interaction frame UMLFrame 184 160 184 80 optional UMLFrame 16 248 360 200 interaction frame -- with inner frames -- -- group=1 UMLFrame 48 304 312 40 interaction frame group=1 UMLFrame 48 368 312 72 interaction frame -- inner group=1 UMLSpecialState 136 88 16 16 type=termination UMLSpecialState 320 200 16 16 type=termination UMLGeneric 136 16 16 48 UMLGeneric 176 16 80 24 _:O1_ bg=orange UMLGeneric 288 16 80 24 _:O2_ bg=red UMLGeneric 208 64 16 80 bg=yellow UMLGeneric 320 80 16 48 bg=red UMLGeneric 16 16 80 24 _:Instance_ Relation 48 32 24 56 lt=. 10.0;10.0;10.0;50.0 Relation 16 88 112 24 lt=<- 10.0;10.0;120.0;10.0 Relation 16 112 112 24 lt=<<<<<- 10.0;10.0;120.0;10.0 Relation 16 128 112 32 lt=<- asyncMsg 10.0;20.0;120.0;20.0 Relation 16 152 112 32 lt=<<- syncMsg 10.0;20.0;120.0;20.0 Relation 208 32 24 48 lt=. 10.0;10.0;10.0;40.0 Relation 320 32 24 64 lt=. 10.0;10.0;10.0;60.0 Relation 216 64 120 32 lt=->> sync call 10.0;20.0;130.0;20.0 Relation 216 112 120 32 lt=<- async return 10.0;20.0;130.0;20.0 Relation 208 136 24 80 lt=. 10.0;10.0;10.0;80.0 Relation 208 216 24 32 lt=. 10.0;10.0;10.0;20.0 Relation 320 120 24 104 lt=. 10.0;10.0;10.0;110.0 Relation 216 192 128 32 lt=-> async return 10.0;20.0;140.0;20.0 UMLGeneric 208 200 16 24 bg=yellow umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Sequence - All in one.uxf0000644000175000017500000000123212533641120023272 0ustar benben 8 com.umlet.element.SequenceDiagram 16 16 304 280 title: sample _alpha:A~id1_|_beta:B~id2_|_gamma:G~id3_ id1->>id2:id1,id2 id2-/>id1:async Msg. id3->>>id1:id1,id3 id1.>id3:id1,id3:async return Msg id1->id1:id1:self iframe{:interaction frame id2->id3:id1,id3:async Msg. iframe} umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/UML Activity.uxf0000644000175000017500000002357312533641120021373 0ustar benben 8 UMLState 208 80 80 32 study bg=red UMLSpecialState 64 80 16 16 type=initial UMLSpecialState 64 104 16 16 type=final UMLSpecialState 24 80 32 32 type=decision UMLState 16 192 80 32 receive signal type=receiver UMLState 16 248 80 32 send signal type=sender UMLTimer 24 296 64 56 time signal UMLObject 16 360 80 32 DataObject UMLSpecialState 240 40 16 16 type=initial UMLObject 112 16 248 456 System valign=top UMLState 16 24 80 32 state UMLSpecialState 232 136 32 32 bg=green type=decision UMLTimer 144 128 48 56 July 1st bg=black UMLState 216 256 80 32 call taxi bg=yellow type=sender UMLState 216 304 80 32 taxi arrived bg=yellow type=receiver UMLState 128 280 80 32 grab bags bg=blue UMLState 176 400 96 32 leave for airport bg=green UMLSpecialState 216 448 16 16 type=final UMLSyncBarHorizontal 24 56 64 16 lw=5 UMLSyncBarVertical 88 72 16 56 template=txt title=titletext bg=red UMLSyncBarHorizontal 184 208 80 16 {joinSpec= date is on or after July 1st and the exam is passed} UMLSyncBarHorizontal 192 368 64 16 lw=5 Text 112 192 88 72 {joinSpec=date is on or after July 1stand the exam is passed} style=wordwrap UMLSpecialState 32 128 16 16 type=flow_final UMLSpecialState 64 128 16 16 type=termination Relation 16 160 96 24 lt=<- 10.0;10.0;100.0;10.0 Relation 240 40 24 56 lt=<- 10.0;50.0;10.0;10.0 Relation 240 104 24 48 lt=<- 10.0;40.0;10.0;10.0 Relation 224 144 136 328 lt=<- m2=[exam missed] 10.0;390.0;150.0;390.0;150.0;10.0;50.0;10.0 Relation 160 136 56 96 lt=<- 50.0;100.0;50.0;10.0;10.0;10.0 Relation 160 208 64 88 lt=<- 10.0;90.0;10.0;60.0;60.0;60.0;60.0;10.0 Relation 232 208 40 64 lt=<- 30.0;60.0;30.0;40.0;10.0;40.0;10.0;10.0 Relation 160 304 64 88 lt=<- 60.0;90.0;60.0;50.0;10.0;50.0;10.0;10.0 Relation 232 328 40 64 lt=<- 10.0;60.0;10.0;20.0;30.0;20.0;30.0;10.0 Relation 216 368 24 48 lt=<- 10.0;40.0;10.0;10.0 Relation 216 424 24 40 lt=<- 10.0;30.0;10.0;10.0 Relation 208 160 88 72 lt=<- [exam passed] 50.0;70.0;50.0;10.0 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML State Machine.uxf0000644000175000017500000000641412533641120024335 0ustar benben 8 com.umlet.element.custom.StateSubDiagram 32 304 96 32 state with substates com.umlet.element.Relation 0 224 120 80 lt=<- self 64;24;32;24;32;64;104;64;104;40 com.umlet.element.custom.State 64 232 80 32 state com.umlet.element.custom.State 24 120 144 88 complex state -- some more... -. com.umlet.element.custom.Decision 120 72 32 32 com.umlet.element.custom.State 24 72 72 32 state com.umlet.element.Relation 0 32 168 40 lt=<- 152;24;24;24 com.umlet.element.custom.SeqDestroyMark 128 16 16 16 com.umlet.element.custom.FinalState 104 16 16 16 com.umlet.element.custom.InitialState 80 16 16 16 com.umlet.element.custom.RegionEndState 56 16 16 16 com.umlet.element.custom.HistoryState 32 16 16 16 umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Sequence.uxf0000644000175000017500000002027212533641120023476 0ustar benben 8 com.umlet.element.custom.SeqObjectActive 208 64 16 80 bg=yellow com.umlet.element.Relation 192 120 40 96 lt=. 24;24;24;80 com.umlet.element.custom.SeqObjectActive 208 200 16 24 bg=yellow com.umlet.element.custom.InteractionFrame 184 160 184 80 optional com.umlet.element.Relation 200 168 144 56 lt=< async. destroy 128;40;24;40 com.umlet.element.custom.InteractionFrame 16 184 144 56 interaction frame com.umlet.element.custom.SeqDestroyMark 320 200 16 16 com.umlet.element.Relation 192 200 40 48 lt=. 24;24;24;32 com.umlet.element.custom.SeqObjectActive 320 80 16 48 bg=red com.umlet.element.Class 288 16 80 24 _:O2_ bg=red com.umlet.element.Class 176 16 80 24 _:O1_ bg=orange com.umlet.element.Note 16 456 240 64 This is a preliminary version of UMLet's sequence diagrams; we are currently working on a more efficient, text-based way of creating them. com.umlet.element.Class 16 16 80 24 _:Instance_ com.umlet.element.Relation 304 16 40 80 lt=. 24;24;24;64 com.umlet.element.Relation 192 16 40 64 lt=. 24;24;24;48 com.umlet.element.Relation 200 40 136 56 lt=<<- sync. call 120;40;24;40 com.umlet.element.Relation 200 88 136 56 lt=< async. return 24;40;120;40 com.umlet.element.Relation 0 104 128 56 lt=< asyncMsg 24;40;112;40 com.umlet.element.Relation 0 72 128 40 lt=< 24;24;112;24 com.umlet.element.custom.SeqDestroyMark 136 88 16 16 com.umlet.element.custom.SeqObjectActive 136 16 16 48 com.umlet.element.Relation 0 128 128 56 lt=<<- syncMsg 24;40;112;40 com.umlet.element.Relation 0 96 128 40 lt=<<<<<- 24;24;112;24 com.umlet.element.Relation 32 16 40 72 lt=. 24;24;24;56 com.umlet.element.Relation 304 104 40 120 lt=. 24;24;24;104 com.umlet.element.custom.InteractionFrame 16 248 360 200 interaction frame -- with inner frames -. -. com.umlet.element.custom.InteractionFrame 48 304 312 40 interaction frame com.umlet.element.custom.InteractionFrame 48 368 312 72 interaction frame -- inner umlet-2015-06-03_UMLet_v13.3/Baselet/palettes/Deprecated - UML Activity.uxf0000644000175000017500000002310512533641120023520 0ustar benben 8 com.umlet.element.custom.FinalState 216 448 16 16 i com.umlet.element.Relation 200 408 40 56 lt=<- 24;40;24;24 com.umlet.element.custom.State 168 400 96 32 leave for airport bg=green com.umlet.element.custom.SynchBarHorizontal 192 368 64 16 com.umlet.element.Relation 216 312 56 80 lt=<- 24;64;24;32;40;32;40;24 com.umlet.element.Relation 144 288 80 104 lt=<- 64;88;64;56;24;56;24;24 com.umlet.element.custom.SendSignal 216 256 80 32 call taxi bg=yellow com.umlet.element.custom.ReceiveSignal 216 304 80 32 taxi arrived bg=yellow com.umlet.element.custom.State 128 280 80 32 grab bags bg=blue com.umlet.element.Relation 144 192 80 104 lt=<- 24;88;24;64;64;64;64;24 com.umlet.element.custom.SynchBarHorizontal 120 168 144 96 {joinSpec= date is on or after July 1st and the exam is passed} com.umlet.element.Relation 216 192 56 80 lt=<- 40;64;40;48;24;48;24;24 com.umlet.element.Relation 144 120 72 112 lt=<- 56;96;56;24;24;24 com.umlet.element.Relation 200 144 88 88 lt=<- m2=[exam passed] 48;72;48;24 com.umlet.element.custom.Decision 232 136 32 32 bg=green com.umlet.element.Relation 224 88 40 64 lt=<- 24;48;24;24 com.umlet.element.custom.State 208 80 80 32 study bg=red com.umlet.element.Relation 224 32 40 64 lt=<- 24;48;24;24 com.umlet.element.custom.InitialState 240 40 16 16 i com.umlet.element.custom.Systemborder 112 16 248 456 topcenter:System com.umlet.element.Relation 0 120 112 40 lt=<- 24;24;96;24 com.umlet.element.custom.Decision 16 80 32 32 com.umlet.element.custom.ReceiveSignal 16 168 80 32 receive signal com.umlet.element.custom.SendSignal 16 224 80 32 send signal com.umlet.element.custom.State 16 24 80 32 state com.umlet.element.custom.Systemborder 16 336 80 32 center:DataObject com.umlet.element.custom.InitialState 64 80 16 16 i com.umlet.element.custom.FinalState 64 104 16 16 i com.umlet.element.custom.TimeSignal 24 272 64 48 time signal com.umlet.element.custom.SynchBarVertical 88 72 16 56 com.umlet.element.custom.SynchBarHorizontal 24 56 64 16 com.umlet.element.custom.TimeSignal 136 128 64 48 July 1st bg=black com.umlet.element.Relation 200 352 40 64 lt=<- 24;48;24;24 com.umlet.element.Relation 208 128 152 344 lt=<- m2=[exam missed] 24;328;136;328;136;24;56;24 umlet-2015-06-03_UMLet_v13.3/Baselet/build.properties0000644000175000017500000000052512533641120020021 0ustar benben#Build Properties are only used for Eclipse Plugin export (during pde.exportPlugins ant call) output..=bin project.path.source=src bin.includes=.,META-INF/,plugin.xml,html/,img/,palettes/,lib/*.jar,custom_elements/ project.website.marketplace=http\://marketplace.eclipse.org/content/umlet-uml-tool-fast-uml-diagrams source..=src/, test/umlet-2015-06-03_UMLet_v13.3/Baselet/ant.xml0000644000175000017500000001642312533641120016114 0ustar benben umlet-2015-06-03_UMLet_v13.3/Baselet/.gitignore0000644000175000017500000000003212533641120016565 0ustar benben/bin/ /log4j.log /export/ umlet-2015-06-03_UMLet_v13.3/Baselet/exe/0000755000175000017500000000000012533641120015363 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/exe/Umlet.ico0000644000175000017500000030253612533641120017156 0ustar benben hV ¨¾00 ¨%f@@ (B;€€ (6}(  @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å' ï] ï] å'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê'÷½üÿýÿþÿüÿ÷¿ë'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë)ûéýÿúñö³ö³úïýÿûéí)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Çýÿø¯áÿÿÿÿÿÿ åø¯ýÿ÷ÇÿÿÿÿÿÿÿÿÿÛÛ1‘[U;Âÿ>Àû®3=Û1Û1Û1Û1¯4=>Àû;ÂÿŒ b[Û1Õý{ýÿýÿô++ÿñ33ÿð ÿì98ÿï""ÿó76ÿù ÿíQPÿøÿô))ÿýÿýÿö{ý{þÿþÿö%%ÿ÷##ÿð,,ÿð*)ÿï..ÿ÷%$ÿýÿò,+ÿú ÿô..ÿýÿþÿö{ò%òKµ?o\¡ÿ`žûßQòKòKòKòKãO`ù\¡ÿ²CqòKì%ÿÿÿÿÿÿÿÿÿ÷×ýÿõ™ÛÿÿÿÿÿÿÙõ™ýÿø×%&Éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî7üóýÿùÙõ“õ“ùÙýÿüóð7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð7ù×ýÿýÿýÿýÿøÙð7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ êGó}ó{ ìCÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ €ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ% éuê¡ òÓ òÓë¡ éuÚ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à=ñ½ùÿýÿþÿýÿþÿþÿýÿùÿïÇ á=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔë‘úýþÿýÿþÿýÿýÿþÿþÿýÿýÿýÿúýì‘ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚñ§ýÿýÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿüÿó§ ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëýÿýÿýÿýÿûûðÉãäOäOäðÁûûýÿþÿþÿýÿíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáQûÿýÿýÿýÿöÓáAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å7÷Óýÿþÿþÿûÿ çGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏòÑýÿýÿýÿõÓ Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßõÓýÿýÿýÿñÛ##ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚEüÿýÿþÿùûÞ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ7ùûýÿþÿûÿÞOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ]ÛaÛaÛa™Z¯v‡ÿvˆÿv‡ÿ… ñÜaÛaÛaÛaÛaÛaÛaÛaÛaÛaÛaÛa†~ñvˆÿvˆÿv‡ÿ–_¹ÛaÛaÛaÕ]ÿÿÿÿÿÿý÷ýÿýÿýÿýÿûÿñ33ÿòJJÿõ ÿüÿïÿôÿôÿî ÿüÿö ÿôEEÿö.-ÿüÿò$#ÿóEDÿöÿýÿó0/ÿùÿýÿýÿýÿýÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿõÿîssÿëÿòZYÿüÿ×``ÿã][ÿä[YÿÕhhÿüÿó]\ÿîÿ÷ ÿúÿë‚ÿâWVÿð;:ÿýÿèccÿûÿþÿþÿþÿþÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿôÿò``ÿ÷ÿò\\ÿüÿ×onÿëKJÿêMKÿÔvuÿüÿô\[ÿö ÿýÿýÿêQPÿå]\ÿó#"ÿùÿèÿøÿþÿþÿþÿþÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿùÿö))ÿûÿö('ÿýÿðCCÿö ÿöÿðCCÿýÿö''ÿúÿþÿýÿýÿûÿýÿýÿôÿþÿýÿþÿþÿþÿö÷ÿÿÿÿÿÿòò•ó•ò•Ð(͹Dÿ¹Dÿ¹Dÿà @õò•ò•ò•ò•ò•ò•ò•ò•ò•ò•ò•ò•Ä ?õ¹Dÿ¹Dÿ¸DÿË.×ò•ò•ò•ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞYýÿþÿýÿöõÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×öñýÿýÿüÿ åYÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØóíýÿýÿýÿð­ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒñ­ýÿýÿýÿôí%&Éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ çoüÿýÿþÿýÿð­ÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙð­ýÿýÿýÿýÿ éoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌñÃýÿþÿþÿýÿöçìÖ9×ÖÖ9ëöçýÿýÿþÿýÿñÃÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßõÍýÿþÿþÿýÿýÿûÿùÿùÿûÿýÿþÿþÿþÿýÿ÷Í æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áòÃýÿýÿýÿþÿýÿýÿþÿþÿþÿýÿýÿüÿòà ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔëoõíýÿþÿýÿþÿýÿþÿþÿýÿõí é{ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ ãc îµ òåöÿöÿòÛ îµ çYÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIHìÕ Ô <;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(0` €%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ??è%%ØC&&ØC>>åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ' æ{ ê· çñô÷øÿøÿô÷ èñ ê· æ{Î' Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ !Å ÝGéµõÿüÿýÿýÿýÿþÿþÿþÿþÿýÿüÿöÿ çÍ ÞGÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ é­øÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿøÿ ë­ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜKñëýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿýÿýÿþÿþÿýÿýÿñë àKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ äIõùþÿþÿýÿþÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿ÷ù çIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßKöùýÿýÿýÿýÿýÿýÿýÿýÿõÿòùñïñïóùöÿýÿýÿýÿýÿýÿýÿýÿþÿ÷ù åKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ+ñõýÿýÿýÿþÿýÿýÿûÿïãå™ÑCPQ×'ÿÿÿÿÿÿSSÙ'Ñ? ç…ïãûÿþÿýÿýÿþÿþÿýÿòõÚ+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕêÅýÿþÿþÿþÿýÿýÿöíá‰Ø ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ åq÷íýÿþÿýÿþÿýÿýÿìÅØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ_ùÿþÿýÿýÿýÿýÿòë â/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å/òëýÿýÿýÿýÿýÿúÿß[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ ëãýÿýÿþÿýÿþÿõí ß/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à/õíýÿýÿþÿþÿþÿíå##ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚGûÿýÿýÿýÿýÿùÿ àqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßqúÿýÿýÿýÿýÿùÿÖ]ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ£ ÷ÿ ÷ÿ ÷ÿ ÷ÿ ÷ÿéãÄ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ æã ÷ÿ ÷ÿ ÷ÿ ÷ÿ öÿß±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛAÛÛÛÛÛÚ°Fï§Sÿ§Sÿ§Sÿ§Sÿ§Rÿ¼JïÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÛ¼Iï§Tÿ§Sÿ§Sÿ§Sÿ§Sÿ®HùÚÜÛÛÛÛÈAÿÿÿÿÿÿýsýÿýÿýÿýÿýÿýÿüÿüÿùÿïÿðÿòÿüÿýÿúÿöÿúÿòÿúÿõÿúÿýÿùÿïÿïÿñÿûÿýÿ÷ÿñ ÿñÿ÷ÿüÿüÿõÿô ÿûÿüÿýÿýÿýÿýÿýÿýÿåsÿÿÿÿÿÿýsþÿýÿýÿýÿýÿþÿþÿýÿë99ÿÿèvtÿÿï ÿýÿáÿ燆ÿâÿù¶´ÿâÿä‘ÿàÿýÿñ&%ÿõªªÿðxwÿònmÿö ÿüÿé]\ÿèxwÿé€ÿî=<ÿýÿýÿïdcÿëllÿúÿýÿþÿýÿýÿýÿýÿýÿæsÿÿÿÿÿÿýsþÿþÿþÿþÿþÿþÿþÿüÿñ|{ÿé))ÿúÿîrrÿð,,ÿýÿÞÿàŒÿæjhÿÜIHÿåcaÿÞ˜˜ÿÜÿýÿî('ÿõrqÿûÿþÿýÿ÷ÿö ŸÿäddÿäiiÿéYYÿúÿþÿîmmÿî#$ÿýÿþÿþÿþÿþÿþÿþÿýÿæsÿÿÿÿÿÿýsþÿýÿþÿþÿþÿþÿþÿûÿñz{ÿí!!ÿüÿóefÿï-.ÿýÿÞÿÙ“’ÿê}ÿéÿé‚ÿÖ ÿÜÿýÿï('ÿõrqÿûÿýÿþÿüÿëggÿáihÿãxvÿíLKÿüÿ÷ÿÿëddÿúÿþÿþÿýÿýÿþÿýÿþÿæsÿÿÿÿÿÿýsýÿýÿýÿþÿýÿýÿýÿüÿóyyÿï ÿýÿõeeÿð--ÿþÿàÿ÷ÒÑÿè;;ÿýÿç:9ÿöÖ×ÿßÿýÿð''ÿöqoÿûÿýÿýÿýÿöÿò! ÿòÿ÷ÿýÿûÿîiiÿì--ÿüÿþÿýÿýÿýÿýÿþÿýÿæsÿÿÿÿÿÿþsþÿþÿþÿþÿþÿþÿþÿýÿöÿøÿýÿöÿ÷ÿýÿöÿó$#ÿ÷ÿýÿ÷ÿó##ÿöÿþÿøÿöÿýÿþÿþÿýÿýÿýÿþÿýÿýÿþÿöÿúÿþÿýÿþÿþÿþÿþÿýÿýÿæsÿÿÿÿÿÿòeòßòßòßóßòßòßåýäÿäÿäÿäÿäÿéûòßòßòßòßòßòßòßòßòßòßòßòßòßòßòßñßòßòßéûäÿäÿäÿäÿäÿæýòßòßòßòßòßòßÝeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA ¸±0Òÿ1Òÿ1Ñÿ1Òÿ0ÑÿFÊÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJÅÝ0Òÿ0Ñÿ1Òÿ0Òÿ0ÑÿE ·ÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙuýÿþÿþÿþÿýÿõûÙ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×1÷ñþÿýÿþÿýÿûÿàuÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ ïýýÿýÿýÿýÿýÿïÁ× ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ ðÁýÿýÿýÿýÿýÿòý%&É!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å•üÿýÿýÿþÿþÿüÿ è¿× ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ× è¿üÿþÿýÿýÿýÿýÿ ã•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏñåýÿýÿýÿþÿýÿüÿîÁÛ1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ1îÁûÿýÿýÿýÿýÿýÿóåØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áWøÿýÿýÿþÿýÿýÿýÿõñ å×/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×/ åôñýÿþÿýÿþÿþÿýÿøÿ áWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ å‘ûÿýÿþÿþÿþÿýÿýÿýÿøû çííŸéŸéŸíŸ çíøûýÿýÿþÿþÿþÿýÿýÿûÿê‘Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì‘ûÿþÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿî‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ç‘ùÿýÿþÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿøÿê‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ åWóåýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿüÿòõ äWÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑê•òýýÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿýÿòýê•Õ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ!ÛðÉóù÷ÿûÿýÿýÿûÿ÷ÿóùðÉ áuÒ!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ10Å%ÓC"!é‘ å‘ å‘çyÓC0/Æ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(@€ Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ11ÄÆE ÞE##éŸã­ã­#"çŸ ßEÇE..ÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ Þq è×íåíÿõÿùÿûÿûÿùÿõÿîÿíå é× ÞqË ÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÓS è¡ñÿùÿýÿýÿþÿþÿýÿþÿþÿþÿþÿþÿýÿýÿùÿòÿäËÔSÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ# âÉõÿüÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿüÿõÿ ãÉÜ#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ ãuñùýÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿüÿñù âuËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ áÅùÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿýÿþÿùÿ äÅÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßêÇûÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿûÿíÇ âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚëÇûÿýÿþÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿüÿíÇ ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ äÅûÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿúÿ çýßýå£ ã• ã•æ£àý èýùÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿûÿ èÅÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ߟúÿýÿýÿýÿþÿþÿýÿýÿýÿüÿóíÝÁØi*+Ù ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×EÜÁõíüÿýÿýÿþÿþÿþÿþÿþÿþÿûÿ áŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Iôýýÿþÿþÿþÿþÿýÿýÿýÿ÷ÿ åÅÓ9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Þ% æ­øÿýÿþÿþÿþÿþÿþÿþÿþÿôýÙIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ È çßüÿþÿýÿþÿýÿþÿþÿýÿó÷ åUÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑ çUô÷ýÿþÿþÿþÿþÿþÿýÿýÿíÉÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ æSøÿýÿýÿýÿþÿýÿþÿþÿò÷ ÞUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßUò÷ýÿþÿýÿýÿþÿþÿýÿøÿÙ}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ äóýÿþÿþÿþÿþÿþÿþÿõÿ áUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ âUöÿýÿýÿýÿþÿþÿþÿýÿ êó##Î ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙKùÿþÿþÿþÿþÿþÿþÿúÿ ã­ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑà­úÿýÿýÿþÿþÿþÿýÿöÿÐqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÅþÿýÿýÿþÿþÿþÿýÿìíÍ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ%ííýÿýÿþÿþÿþÿýÿüÿåÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™b 5 Éß,Ùÿ,Ùÿ,Úÿ,Úÿ,Úÿ,Ùÿ-×ÿO'ÐÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW.ÇÑ,Úÿ,Úÿ,Úÿ,Ùÿ,Úÿ,Ùÿ,Ùÿ9 Èïs+'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ۳ۿܿۿۿۿۿܿÒÏÁ3ÿ¿5ÿ¿5ÿÀ5ÿ¿6ÿ¿6ÿ¿5ÿ¿4ÿÑ *óÛ¿Ü¿Û¿Û¿Ü¿Û¿Û¿Ü¿Û¿Ü¿Û¿Û¿Ü¿Û¿Û¿Û¿Û¿Ü¿Û¿Û¿Û¿Û¿Ü¿Û¿Ñ )ó¿6ÿ¿6ÿ¿6ÿ¿6ÿ¿5ÿ¿6ÿ¿6ÿÁ2ÿÓÏۿܿۿܿۿۿܿϳÿÿÿÿÿÿÿÿÿÿÿÿüïüÿüÿüÿüÿüÿüÿüÿüÿüÿüÿüÿúÿõÿôÿöÿúÿüÿüÿüÿúÿúÿüÿúÿúÿüÿúÿúÿüÿüÿüÿùÿøÿøÿøÿûÿüÿüÿûÿøÿõÿ÷ÿúÿûÿüÿüÿúÿõÿøÿüÿûÿüÿüÿüÿüÿüÿüÿüÿüÿíïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿùÿã65ÿñ““ÿñ•”ÿïŽÿå(&ÿúÿþÿûÿá..ÿæJIÿîÿíYXÿìXWÿîÿãOOÿá32ÿûÿþÿòÿñ€ÿð‹Šÿð‰ˆÿñˆˆÿó..ÿûÿýÿèÿî|zÿÿÿç! ÿýÿþÿýÿì"!ÿñ™˜ÿ÷=>ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿøÅÅÿÞAAÿæÿÞXWÿõ«©ÿïÿþÿúÿÔKKÿÞvvÿÞÿîŸÿò¦¥ÿÛÿÙ~ÿÔQQÿúÿþÿìÿû¹¸ÿâ..ÿëÿìÿö ÿýÿúÿívuÿÜ`_ÿ×ÿÕ??ÿãYXÿùÿýÿþÿéFFÿä„„ÿõÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿõÄÄÿëÿýÿëÿû¹¹ÿêÿþÿúÿÓKKÿØvuÿá_]ÿáa_ÿá]\ÿáWUÿÓ~ÿÔQQÿúÿþÿëÿü¶µÿïÿýÿþÿþÿþÿóÿúœÿê–•ÿòÿ뇇ÿõ‘ÿïÿýÿþÿéGGÿéz{ÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿö¾¿ÿîÿýÿñ ÿú·¶ÿêÿýÿúÿÓJKÿÏzxÿ隘ÿäÿãÿé›ÿÉ„ÿÔQQÿúÿþÿëÿü¶µÿïÿýÿýÿýÿþÿûÿéa_ÿ臆ÿÏ"!ÿßnmÿï}|ÿ÷ÿýÿöÿähiÿ唕ÿòÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿö¾¾ÿïÿýÿò ÿú¶¶ÿêÿýÿúÿÔKKÿç«©ÿè{zÿöÿõÿç{zÿß±±ÿÔQQÿúÿþÿëÿüµ´ÿïÿýÿýÿýÿþÿýÿìÿìVUÿù‚ÿïdbÿé ÿýÿýÿõ ÿêÿí±±ÿõ/.ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿð ÿøššÿóÿýÿõ ÿú””ÿïÿþÿûÿÝ==ÿýÀ¿ÿè#"ÿûÿüÿè! ÿü¼¼ÿÞBCÿûÿþÿðÿû”’ÿóÿýÿþÿþÿþÿýÿýÿûÿöÿûÿýÿþÿþÿþÿñ##ÿî==ÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿó ÿüÿþÿûÿó ÿûÿýÿýÿõÿð ÿùÿýÿýÿùÿð ÿõÿýÿþÿûÿó ÿúÿþÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿþÿúÿøÿþÿþÿüÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿôïôÿôÿôÿõÿõÿôÿôÿóÿñÿñÿñÿñÿñÿñÿñÿñÿòÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿóÿôÿôÿôÿòÿñÿñÿñÿñÿñÿñÿñÿñÿóÿôÿôÿôÿôÿôÿôÿôÿæïÿÿÿÿÿÿÿÿÿÿÿÿå'å)å)æ)ç)æ)å)æ)Ë Eˆvï€ÿ€ÿ€ÿ€ÿÿÿ€ÿ¤$Ùå)æ)å)å)æ)æ)å)å)æ)æ)æ)å)å)æ)æ)æ)å)å)æ)å)å)å)å)å)©(yÙ€ÿ€ÿ€ÿÿ€ÿ€ÿ€ÿ‡wÿ¯Caæ)å)å)æ)æ)å)å)Ù'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ âÙýÿþÿþÿþÿýÿýÿýÿ çÙ((È ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâÑýÿþÿýÿþÿýÿýÿýÿ ëÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ‰ýÿþÿþÿþÿþÿþÿþÿôÿÛaÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Uöõýÿþÿýÿþÿýÿýÿùÿ݉ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ ïÿþÿýÿýÿýÿþÿþÿýÿïÕ Üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜðÕýÿþÿýÿýÿýÿýÿýÿðÿ%&È9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃà¹üÿþÿþÿþÿþÿþÿþÿüÿ æËÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ çËûÿþÿþÿþÿþÿýÿýÿûÿ á¹ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ=ïûýÿþÿþÿþÿþÿþÿþÿûÿ åËÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ åËúÿþÿýÿýÿþÿþÿþÿýÿñûÔ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â…ùÿþÿýÿýÿþÿþÿþÿþÿüÿíÕÛUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙUîÕûÿýÿþÿýÿýÿþÿýÿþÿûÿ â…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌîÍýÿýÿýÿþÿþÿþÿþÿþÿýÿôõ ç§Ì-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ- æ§óõýÿýÿþÿýÿþÿþÿþÿþÿýÿìÍÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏIðóýÿýÿþÿþÿþÿþÿþÿýÿýÿüÿóÿ êÛÕ• !×MÙ+Ô+Ô+Ø+"!ØMÕ• éÛóÿüÿýÿþÿþÿþÿþÿþÿþÿþÿýÿòóØIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßOô÷ýÿýÿþÿþÿþÿþÿþÿýÿýÿýÿýÿùÿöÿõÿóÿóÿôÿöÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿö÷ æOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ åKô÷ýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿö÷ èKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áOðóýÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿòó ãOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒIñÍúÿýÿþÿþÿýÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿúÿïÍÖIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ ç…ñûýÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿýÿýÿýÿñû â±ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ= ä¹òÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿýÿòÿ ä¹Ú=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÓ9سìÙ÷ÿúÿûÿüÿýÿþÿþÿýÿüÿûÿúÿ÷ÿìÙ à‰Ó9ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖCÓ“Ú­íå îÿïÿïÿ îÿ ìÃÛ­Ó“×CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIHì$#ØÒÒ##×<;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿCCëA32ß[%$Ø[ Õ[ Õ[&&Ø[21Þ[BBèAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ11Ä[À‡̇؇ ã‡ëÝéÿèÿçÿçÿèÿèÿêÝ ä‡Ú‡·À‡..Ã[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿЯ׳ Þ³ÜçÛÿ äÿêÿðÿôÿ÷ÿùÿùÿùÿùÿ÷ÿóÿðÿëÿ äÿ ÜÿÜç Þ³Ù³Ò¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÚÇmÓß éßóÿøÿúÿúÿûÿüÿüÿüÿýÿýÿýÿþÿýÿýÿýÿýÿüÿýÿüÿüÿúÿúÿùÿóÿ éßÔßÉmÚ Ó ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃ#Ö;éO áÿëÿòÿøÿûÿýÿýÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿûÿøÿòÿëÿ âÿÚñÖ;Ä#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÖgÕ¿ áÿóÿûÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿôÿ àÿÖ¿ÖgÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆ ã«éÿòÿøÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿóÿéÿ â«Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ؇à÷ñÿúÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿûÿñÿ â÷܇ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜÒe ßëóùûÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿýÿýÿûÿõù ÞëÑe ÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ; åièÿõÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿõÿ èÿ åiË;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐMÔéïÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿúÿðÿØéÔMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔO àßóÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿòÿ åßÚOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛA ãåóÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿýÿüÿõÿ ååÝAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßA æùøÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿýÿûÿêù âAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝA çù÷ÿüÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿþÿýÿøÿêù ßAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚO æåöÿýÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿýÿûÿ æå ßOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒM âßöÿüÿýÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿ÷ÿñÿíÿêÿéÿ æÿ åÿ äÿ äÿ åÿ æÿ éÿëÿîÿòÿ÷ÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ éßÚMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ= Ýéóÿüÿýÿýÿþÿþÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿûÿôÿ ãýÏû&&ÌûEGÙû>?ÞeÛ)Ù)Ø)Ø)Ù)Û)A@àeHHÛû&'ËûÐû åûóýúÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿõÿ ÞéÓ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÒÿóÿýÿýÿýÿýÿþÿþÿýÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿýÿûÿöÿêÿàïÙÏ""×Ï*+Ù!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓEØÏàï éÿ÷ÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿÙÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÞeïÿúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿüÿøÿïÿëµÔ£('Åoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*)ÅoÑ£íµñÿøÿûÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿìÿ ÛeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËg äõüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿûÿôÿàÿÕ©ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ ßw çÁòÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿøÿ åõÏgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ¿ñÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿüÿøÿìÿÞÍÓK##Ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ü)ÚÍíÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿøÿ Þ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&%ÂÕ‰í÷úÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿ÷ÿ èó å-ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑ å-êóúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿê÷Ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÈgÛÿøÿýÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿüÿòÿ ãÝ Û1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ý1 äÝóÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿøÿî«Ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ãgîÿüÿýÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿüÿôÿ âÕ×AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØA ãÕòÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿðÿÖ¥ !ÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ# é¿ùÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿôÿ áÝØAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×A áÝöÿüÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿ÷ÿßÿÔ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$$Ä ÍÏîÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿøÿ ãóØ1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ1 äó÷ÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿûÿòÿÖÏÎ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ Ýÿõÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿùÿ çÿ ß-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à- éÿüÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿ áÿ'%Î#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØIñÿûÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿïÿÓÍÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑØÍìÿúÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿìÿ*(ÊßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚßûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ åÁØ)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ) ÝÁôÿýÿýÿüÿýÿþÿþÿþÿþÿþÿþÿþÿýÿüÿýÿóÿ×ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ33Çq áóþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿ âÿÏwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕw èÿùÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿùÿ éó%%Õqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɳ èÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿÛµÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ ÞµðÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿôÿÔ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Û³ íÿøÿøÿøÿøÿùÿøÿøÿøÿøÿøÿøÿøÿøÿ õÿ èÿ-'Ö£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ81Ë£Þÿøÿøÿøÿøÿøÿøÿùÿøÿøÿøÿøÿøÿøÿøÿ ôÿÖ¿c5¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™b-_ ¥ËT µÿQºÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ¼ÿQ»ÿQºÿQºÿQºÿT ¶ÿg³ÿ¬aÓ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸nÉ£l!¬ÿQ»ÿQ¼ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQºÿQºÿQ¹ÿT¸ÿc ÿu*‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌoÍÍËÍÍËËËËÌÍÍËÍÍÊ µ3éMÿ¥Rÿ¤Rÿ¥Sÿ¤Sÿ£Sÿ¥Sÿ¥Sÿ¤Sÿ¤Tÿ¤Uÿ¤Tÿ¤Rÿ¥Sÿ¤Sÿ¦Oÿ³ JÿÓ%JÑÌÍÍÍÌÍÌÌÍÍËÍÍËÌÍÌÌÍÌËÍÍËÍÍÌÌÍÌËÍÍËÍÍËÌÍÌÌÍÍÌÍÍËË×)EѲJÿ¤Tÿ¥Vÿ¤Tÿ¤Sÿ¥Sÿ¥Sÿ¤Sÿ¤Sÿ¥Sÿ¤Sÿ¤Tÿ¥Sÿ¤Sÿ¤Sÿ¦Rÿ«Gÿ·1ÃÊÍÌÌÍÌÌÍÍËÍÍËÌÍ̵ oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâßãÿãÿâÿãÿãÿâÿâÿâÿâÿâÿãÿãÿâÿãÿãÿáÿÞÿÛÿÚÿÚÿÚÿÚÿÙÿÚÿÛÿÚÿÚÿÚÿÙÿÚÿÚÿÚÿÚÿÞÿà ÿâÿãÿãÿãÿâÿâÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿãÿãÿãÿâÿâÿàÿÜÿÙÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÙÿÜÿÞÿáÿãÿâÿãÿäÿãÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿÆßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûßûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿúÿúÿúÿúÿúÿúÿúÿùÿøÿøÿ÷ÿøÿúÿúÿúÿûÿûÿûÿûÿûÿûÿúÿùÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿùÿøÿúÿûÿûÿùÿùÿúÿúÿúÿúÿúÿúÿúÿùÿøÿøÿùÿúÿúÿøÿùÿûÿûÿúÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿÛßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿøÿôÿðÿï ÿñ ÿðÿôÿùÿüÿýÿþÿþÿþÿýÿýÿûÿùÿùÿúÿýÿüÿúÿöÿöÿûÿýÿüÿúÿøÿùÿûÿýÿþÿþÿþÿþÿüÿ÷ÿõÿõÿõÿõÿõÿõÿöÿùÿüÿýÿþÿþÿþÿýÿúÿöÿóÿòÿò ÿóÿöÿùÿúÿüÿþÿþÿþÿýÿþÿýÿ÷ÿóÿò ÿôÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿùÿèÿÝÿáFFÿèggÿñutÿðusÿã^]ÿß<;ÿßÿîÿúÿþÿþÿþÿýÿûÿéÿç.-ÿïEDÿãÿõÿôÿê ÿäEDÿäGEÿé ÿõÿõÿàÿíMMÿç21ÿèÿúÿþÿþÿþÿþÿïÿè65ÿâQPÿâQQÿâQPÿâQPÿâQQÿâQPÿåPOÿï00ÿñÿúÿþÿþÿýÿõÿãÿá)'ÿäTRÿñonÿôsrÿè^]ÿä76ÿßÿîÿüÿþÿþÿþÿýÿþÿõÿæÿçYWÿôurÿ÷WWÿõ ÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîÿÚ$#ÿí——ÿÿÓÒÿýÍÍÿñ³²ÿò¸¶ÿÿÓÒÿúÊÊÿëyxÿÛÿóÿþÿþÿþÿþÿøÿÓÿá„…ÿÿÈÇÿÉÿëÿãÿèFEÿüÍÌÿüÑÏÿè?=ÿæÿêÿÀ ÿÿßàÿäÿÑÿ÷ÿþÿþÿþÿþÿßÿü›™ÿÿßßÿÿÈÇÿÿÂÀÿÿÂÀÿÿÁÂÿÿÁÁÿÿÀ¿ÿÿuuÿì ÿøÿþÿýÿýÿéÿÞA?ÿô¯­ÿÿÆÄÿÿç¡ ÿø¾½ÿú¾½ÿêedÿåÿüÿýÿþÿþÿþÿýÿìÿéigÿþåãÿë³²ÿú‚ÿôÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿàÿò‰ˆÿÿæçÿè——ÿÐ<;ÿÕ('ÿÖ*)ÿÔMLÿîµµÿÿãáÿÛPNÿçÿþÿþÿþÿþÿ÷ÿÌÿÜÿÿÖÕÿÀÿäÿÑ ÿåŽÿÿ¾¼ÿÿÕÓÿé‹ÿÐ ÿãÿµ ÿÿïðÿà›œÿÉÿöÿþÿþÿþÿþÿÛÿü§¦ÿøÑÏÿÜWVÿÖ77ÿÝ76ÿÞ66ÿÞ66ÿâ65ÿí ÿòÿûÿþÿýÿúÿÚÿø³±ÿõ¸·ÿßKIÿÕ#"ÿÔÿÚ65ÿì•”ÿÿÎÍÿó55ÿúÿüÿþÿþÿþÿýÿêÿ犉ÿÿäãÿÂ89ÿéÿôÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿÙ ÿûÛÛÿöÉÉÿÜ/.ÿåÿöÿöÿÙÿÞWVÿþÙØÿûžœÿÜÿþÿþÿþÿýÿ÷ÿËÿÛÿÿÖÖÿ¼ÿÜÿä=<ÿüÆÄÿ×jhÿêwvÿöÁÀÿÝ32ÿÛÿ²ÿÿïðÿà›œÿÈÿöÿþÿþÿþÿýÿÙÿû§¦ÿüÅÃÿë*)ÿëÿ÷ÿùÿùÿùÿûÿýÿýÿþÿüÿôÿè75ÿûßßÿÖmmÿÆÿØ ÿÚ ÿÒ ÿ½%%ÿ¿BAÿÛÿóÿûÿýÿýÿþÿþÿêÿç‹‹ÿÿÛÛÿÑÿûÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿ÷ÿãÿüååÿî­¬ÿ×ÿøÿýÿüÿìÿæ&&ÿù¼»ÿþ»ºÿØÿþÿþÿþÿþÿ÷ÿËÿÛÿÿÖÖÿ¶ÿÓÿìÿúÄÃÿÎ)(ÿÍ#"ÿûÂÀÿêtrÿÔ ÿ®ÿÿïðÿàœ›ÿÈÿöÿþÿþÿþÿüÿØÿû¨§ÿýÅÃÿï))ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿúÿëÿüVUÿúèéÿ触ÿ톅ÿö„„ÿ÷„„ÿó……ÿ興ÿéŽÿôUUÿçÿ÷ÿýÿþÿþÿþÿêÿ狌ÿÿÛÜÿÓÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿâÿüããÿð››ÿßÿýÿþÿýÿôÿèÿõ³³ÿþ¼»ÿ×ÿþÿþÿþÿþÿ÷ÿËÿÛÿÿÑÑÿ¬ÿÇ0.ÿÿº¸ÿâ„‚ÿÚÿÚÿã€ÿü°®ÿÌ,*ÿ¡ÿÿíëÿàœ›ÿÈÿöÿþÿþÿþÿýÿÙÿû§¦ÿýÅÃÿï))ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿûÿïÿóIGÿþìíÿî®­ÿå{zÿíyyÿïyxÿêzyÿæ––ÿùÜÝÿÿ„„ÿçÿøÿýÿþÿþÿþÿêÿ狌ÿÿÛÜÿÓÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüâãÿðššÿßÿýÿþÿüÿ÷ÿêÿö²²ÿþ¼»ÿÖÿþÿþÿþÿþÿ÷ÿËÿÛŽÿÿÐÏÿ¡ÿÆbaÿÿÄÃÿÚDBÿâÿâÿÕDCÿÿÅÄÿÇecÿ•ÿÿèåÿàœ›ÿÈÿöÿþÿþÿþÿþÿÙÿû§¦ÿýÅÃÿï))ÿðÿýÿþÿþÿþÿþÿþÿþÿþÿüÿ÷ÿÞ"ÿþØ×ÿéÿÌÿÓÿ×ÿÌ ÿÕccÿù××ÿéRRÿîÿúÿþÿþÿýÿõÿÙÿàŒÿÿÜÜÿÂÿíÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüâãÿðššÿáÿýÿþÿýÿøÿìÿ÷±²ÿþ¼»ÿÖÿýÿýÿþÿýÿ÷ÿËÿÛÿÿÐÏÿŸ*(ÿó¬«ÿÿàÿòÿðÿãÿôœ›ÿ쮬ÿ”($ÿÿéæÿßœ›ÿÈÿöÿþÿþÿþÿþÿÙÿû¦¦ÿýÅÃÿï))ÿðÿüÿþÿýÿüÿýÿþÿþÿþÿýÿûÿá ÿé~ÿüßÞÿñ–”ÿÐEEÿÄ75ÿâxvÿøÑÐÿü«ªÿßÿ÷ÿüÿýÿüÿüÿèÿêYYÿì·¹ÿÿéêÿÖrrÿóMLÿð ÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿâÿüâãÿðššÿáÿþÿþÿýÿøÿíÿ÷±²ÿþ¼»ÿÖÿýÿýÿþÿýÿ÷ÿËÿÛÿÿÎÌÿ¯SQÿýÔÒÿèSRÿìÿýÿûÿëÿäYWÿüÖÔÿžOLÿÿéçÿàœœÿÈÿöÿþÿþÿþÿþÿÙÿû¦¥ÿýÅÃÿï*(ÿðÿüÿþÿýÿüÿýÿþÿþÿþÿþÿýÿîÿÙÿïwwÿúËÈÿûÕÓÿúÔÓÿúÒÐÿú›™ÿÜ.-ÿåÿüÿýÿýÿüÿüÿç&&ÿø»»ÿúèéÿÿö÷ÿõÖÖÿû£¢ÿøÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüââÿñ™šÿâÿþÿþÿýÿøÿíÿ÷±²ÿþ»»ÿ×ÿþÿþÿþÿýÿøÿÌÿÜ‘ÿÿÓÑÿð¹¶ÿî®­ÿÏÿóÿýÿýÿòÿÑÿ맦ÿâ©©ÿÿåæÿàœœÿÉÿöÿþÿþÿþÿþÿÚÿû¦¦ÿýÅÂÿï)'ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿðÿãÿãÿõ.-ÿø32ÿêÿÞÿìÿ÷ÿýÿþÿþÿþÿýÿóÿÖÿߌŒÿÿÛÛÿÁÿéÿøÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿéÿýààÿò—˜ÿäÿþÿþÿýÿøÿñÿù°°ÿþ¸¹ÿÜÿþÿþÿþÿýÿøÿÑÿßÿÿçæÿÿçåÿðihÿÚÿ÷ÿþÿþÿøÿÛÿía`ÿÿÚÚÿÿìíÿãšœÿÏÿ÷ÿþÿþÿþÿþÿÞÿü¥£ÿþÃÁÿô)'ÿñÿüÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿûÿ÷ÿñÿñÿ÷ÿúÿýÿþÿþÿþÿþÿþÿþÿþÿñÿïmlÿÿ¬¬ÿâÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿ÷ÿìÿýÿôbbÿëÿþÿþÿýÿùÿòÿùqrÿùwwÿåÿþÿþÿþÿþÿùÿÜÿç]\ÿúŸŸÿü“’ÿçÿðÿûÿþÿþÿüÿñÿçÿú‹ŠÿúžŸÿëdfÿÝÿùÿþÿþÿþÿþÿçÿökiÿü}|ÿóÿõÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿûÿûÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿøÿëÿè0/ÿïÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿòÿèÿéÿöÿþÿþÿýÿüÿöÿëÿæÿóÿþÿþÿþÿþÿüÿðÿé ÿâÿäÿïÿúÿüÿýÿþÿýÿúÿïÿåÿâÿêÿñÿüÿþÿþÿþÿþÿôÿèÿëÿõÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿüÿóÿîÿøÿþÿþÿþÿþÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿýÿþÿþÿýÿýÿýÿýÿþÿýÿýÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿûÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûßûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿûÿúÿúÿûÿüÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿùÿûÿûÿûÿûÿûÿûÿúÿúÿùÿøÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿÜßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíßîÿíÿíÿîÿíÿîÿíÿîÿîÿîÿîÿíÿíÿîÿíÿíÿêÿè ÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿé ÿëÿìÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿîÿíÿîÿíÿîÿîÿíÿîÿíÿîÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿìÿìÿìÿíÿíÿîÿíÿîÿìÿìÿé ÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿèÿèÿê ÿëÿìÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿÑßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåIæSåSåSæSåSæSåSçSçSçSæSåSåSæSåSåSÃ)­·<ÿµAÿ´Bÿ´Bÿ´Bÿ´BÿµBÿ´Bÿ´Aÿ´BÿµBÿµBÿµBÿ´Bÿ´Bÿµ@ÿ¼<ÿ×<ÁåSæSåSæSåSåSæSåSæSåSåSæSåSæSåSåSæSåSæSæSåSæSåSæSæSåSæSåSæSæSåSæSåSåSæSåSæSåSåSåSåSåSåSåSæSåSæSåSÚ7Á¾;ÿ´Cÿ´Bÿ´Bÿ´BÿµBÿ´Bÿ´Bÿ´Bÿ´Bÿ´Bÿ³Bÿ³Bÿ³Bÿ´Cÿ¶Bÿ¹8ÿÅ&­äSåSæSåSåSæSåSæSåSåSæSåSæSåSåSæSÊIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©CX ¯¿O »ÿLÀÿMÀÿMÀÿLÀÿMÀÿLÀÿM¿ÿMÀÿMÀÿMÀÿNÀÿMÀÿL¿ÿM »ÿc¹ÿªfÜ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·sÏ£h#²ÿL¿ÿL ÀÿMÀÿLÀÿMÀÿLÀÿMÀÿMÀÿLÀÿL ÀÿL ÀÿL¿ÿL¿ÿL ÀÿN ½ÿ^¤ýr*ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ݳñÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿûÿ ìÿ Õ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ))Ì£ãÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿýÿýÿýÿþÿùÿ ݳÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɳ çÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿöÿÛÅ((È-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à£ðÿýÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿýÿüÿõÿÕ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-,ÅQ áíþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿûÿ åÿÔwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜAîÕùÿýÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿýÿøÿ éí ÓQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙßúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ áÙÒ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ7ÙÙôÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿóÿÔßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ý#ðÿúÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿýÿüÿîÿ äW ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ß æWîÿûÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿýÿëÿ'(ÇÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÛÿõÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿùÿ èÿÜQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜQêÿüÿýÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿýÿúÿ ßÿØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà Í­íÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿ ã÷ÐSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕS å÷÷ÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿúÿðÿØ­Ï ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ;ãÿøÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿôÿ àçÕ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ[ àç÷ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿöÿÜÿÐ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÞ‰íÿûÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿ ßçÎSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓS áçóÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿïÿ؉ÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ[Úóøÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿôÿ ã÷ÛQÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÛQ â÷óÿûÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿ÷ÿ ãóÏ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØiííùÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿøÿ æÿ áWÑ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ7 áW çÿøÿüÿýÿþÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿüÿëíÜiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ¿ñÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿìÿÞÙÚAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕAÝÙîÿùÿüÿýÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿüÿöÿÜ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌE ãóüÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿòÿ çÕÙ£Ó!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ!Ø£ åÕñÿüÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿ÷ÿ äóÐEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áAîÿúÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿúÿóÿ åÙ̱ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɱ çÙñÿùÿüÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿìÿ ßAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÏáðÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿüÿ÷ÿîÿ äûÚûÚoÖ)!!Ã);<Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ==Í Â)Ö)ÙoÚû åûíÿ÷ÿüÿýÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿûÿòÿÙáÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ/ ßÏñÿüÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿùÿðÿ ßÿÏÿ%&ÖÁ ÞWÚWØWÕWÔWÔWÕW×WÚW ÞW'&×ÁÏÿ ßÿîÿúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿôÿ áÏ×/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×9 âÍôÿüÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿûÿ÷ÿóÿñÿîÿìÿëÿéÿéÿéÿéÿêÿìÿîÿñÿóÿ÷ÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿýÿýÿöÿêÍß9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ3 æÛöÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿýÿûÿ çÛ â3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â æñöÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿ÷ÿ êñ ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â æÛõÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿûÿøÿéÛ ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ3 äÍñÿüÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿûÿôÿ æÍ á3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ9 àÏñÿúÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿûÿðÿ åÏÞ9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ/ÒáñÿýÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿýÿþÿûÿñÿÖáÚ/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ æA èóóÿûÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿýÿýÿüÿýÿüÿóÿ åó äAÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔE â¿ðíøÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿüÿùÿñÿÞáÐEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜiÜóóÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿñÿ ßóÚ“ÐOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ[ æ‰ çÿðÿøÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿñÿ æÿ ã‰Î[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÚ;Ó­ áÿõÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ áÿÔ­Ù;ÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ ÜÒÑ Þé åÿïÿ÷ÿüÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿüÿ÷ÿîÿ çí ßßÒÑÜÊ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/-Â3$#Ƴ׳í³ïýòÿõÿ÷ÿøÿùÿûÿüÿýÿþÿþÿþÿþÿþÿýÿýÿüÿûÿùÿøÿöÿõÿóÿîýì³سÉQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓƒÙ‡ÚÃÕÿÚÿ äÿìÿóÿ÷ÿûÿýÿþÿþÿýÿûÿ÷ÿòÿìÿ äÿÚÿÕÿÚÃÛ‡ÒƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA@Ì-))Â[Ç[Ö[('è—0/ëÿåÿàÿ áÿ âÿ âÿ áÿàÿäÿ! è³ â[Ö[Ç[)(Ã[?=Ì-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRRñFEê/..Ý/Ò/Ñ/Ó/Ó/Ñ/Ò/,,Ü/<;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿumlet-2015-06-03_UMLet_v13.3/Baselet/exe/launch4j_project.xml0000644000175000017500000000113112533641120021337 0ustar benben true gui .\umlet.jar Umlet.exe normal http://java.com/download false Umlet.ico false 1.6.0 preferJre umlet-2015-06-03_UMLet_v13.3/Baselet/exe/umlet.sh0000644000175000017500000000067212533641120017052 0ustar benben#!/bin/sh # Shell script for running umlet from the command prompt in linux # If you want to put umlet.sh in your home bin directory ($HOME/bin/) to start it from anywhere with # $ umlet.sh myDiagram.uxf # you must specify the programDir directly instead #programDir=/path/to/umlet programDir=$(cd $(dirname $0);pwd) if [ $# -eq 1 ] then java -jar ${programDir}/umlet.jar -filename="$1" else java -jar ${programDir}/umlet.jar "$@" fi umlet-2015-06-03_UMLet_v13.3/Baselet/exe/umlet.desktop0000644000175000017500000000034412533641120020105 0ustar benben[Desktop Entry] Encoding=UTF-8 Type=Application Name=UMLet GenericName=UMLet Comment=Free UML Tool for Fast UML Diagrams Exec=java -jar umlet.jar Icon=img/umlet_logo.png Terminal=false Categories=Development; StartupNotify=true umlet-2015-06-03_UMLet_v13.3/Baselet/exe/Umlet.exe0000644000175000017500000036100012533641120017154 0ustar benbenMZÿÿ¸@€º´ Í!¸LÍ!This program cannot be run in DOS mode. $PELøI…Rà @žŽP@ øÝ@ ” ü‰ü„.text¨?@ 0`.dataÀPD@0À.rdata`F@0@.bss°Œp€0À.idata”  L@0À.rsrcü‰ŠX@0ÀU‰åƒì‰]ø‹U1Û‰uü‹1ö‹=‘ÀwC=Àr[¾Ç$1Ò‰T$èÔ<ƒøtz…ÀtÇ$ÿлÿÿÿÿ‰Ø‹uü‹]ø‰ì]Â=”ÀtÂwJ=“Àt´‰Ø‹uü‹]ø‰ì]Â=Àt[=ÀuÅÇ$1ö‰t$èp<ƒøtj…ÀtªÇ$ÿÐëš=–ÀëÑÇ$¹‰L$è@<…ö„vÿÿÿè³9élÿÿÿÇ$ 1ɉL$è<ƒøt0…À„RÿÿÿÇ$ ÿÐé?ÿÿÿÇ$¸‰D$èì;é%ÿÿÿÇ$ »‰\$èÒ;é ÿÿÿ¶¼'U‰åSƒì$]øÇ$@è¢<ƒìè"9ÇEø¸p@Uô‰\$‹ P@‰D$‰T$‰L$ Ç$p@è‰;¡Àû@…ÀtX£ P@‹¨A…Ò…‹ƒúàt ¡Àû@‰D$‹¨A‹K0‰ $èF;‹¨AƒúÀt‹Àû@‰\$‹ ¨A‹QP‰$è ;è;‹ P@‰èN8ƒäðèî:‹‰L$‹p@‰T$¡p@‰$è 7‰ÃèÂ:‰$èÊ;‰D$‹¨A‹B‰$èÅ:‹¨AéUÿÿÿv¼'U‰åƒìÇ$ÿŒAèÈþÿÿ´&U‰åƒìÇ$ÿŒAè¨þÿÿ´&U‹ ÄA‰å]ÿát&U‹ °A‰å]ÿáUº€‰åW1À½èþÿÿVSì‰T$‰D$‰<$è?:‰|$Ç$è …À„|Ç$1É1Û‰\$1ö‰L$ ‰t$è™;ƒì…À‰ÃtUµhÿÿÿ‰ö‰t$¸‰D$‰$è{;ƒì ‰|$‰4$èì9…Àu/‰\$1É1Ò‰L$ ‰T$Ç$èD;ƒì…À‰Ãu³eô1À[^_]Ãeô‰Ø[^_]Ãë U‰åWVSì|‹u‰4$èù=·„÷Htè¸eô[^_]´&Ç$1Ûè …À…‰p@1ÿÇ$ è¦ …Àt‰4$»`@‰\$è!9…À„W‰=p@¡p@…Àu…ÿ„A1É1À1Û‰L$,¿€‹U‰D$$¹€1À‰T$(1Ò‰\$ »€‰|$¿`@‰L$¹`@‰T$‰D$‰\$ ‰|$‰L$Ç$€è,:£ü@‹p@ƒì0…Ò„Ÿü1ÀØþÿÿ¹‰ßó«flj\$Ç$è' …À…zÇ$1ÛèÁ …Àt‰4$¿`@‰|$è<8…Àu»‰ü@¿@1ÛÇ$èŠ £ðû@1Ò1À‰|$¹‰T$‰\$ ‰D$‰L$‹u‰4$è}9ƒì…À„gþÿÿ‰D$ 1Ò»r‰T$µÈþÿÿ‰\$¡ü@‰$èT9ƒì‰t$‹ ü@‰ $èG9ƒìÇ$è@9‹½Èþÿÿ‰Ãƒì‹•ÐþÿÿÇ$)ú)Ó‰ØÁè<è9‹µÌþÿÿƒì»‹ÔþÿÿÑÿ‰\$‰|$)ñ)ȉÂ1ÉÁê‰L$Ð1ö‰t$1ÒÑø‰T$‰D$ ‹ü@‰$èÐ8‹Eƒì‰D$‹ ü@‰ $èÀ8‹5ü@ƒì‰4$è·8¡ü@ƒì‰$¹è¾0@‰t$ ¿‰L$‰|$è”8ƒì…À„FýÿÿÇ$è1@„3ýÿÿ¡p@…Àu‹p@…Û„€½¨þÿÿë‰<$èW8ƒì‰<$èT8ƒì‰<$1À1ɉD$ 1ö‰t$‰L$è?8ƒì…ÀuÉ‹ ü@…ÒuLèY0¡p@eô[^_]‰4$¿,`@‰|$è)6…À…×üÿÿ»éÍüÿÿ¡ ü@…Àu`è01Àé‘üÿÿ‹=p@»<`@‰\$‰$‰|$è×5ë—‰$èÕ5Xÿûƒvº<‰P@écýÿÿ¿éŸüÿÿ£P@éOýÿÿ‰D$ ¿ º‰|$‰T$Ç$K`@èl5éyÿÿÿº€1Àµèþÿÿ‰T$‰D$‰4$èR5‰t$Ç$è…Àu01Û‰$¾‰t$èû6ƒì‰$è 7ƒìèÀ¸éµûÿÿÇ$1Û1ɉ\$1ÿ‰|$ ‰L$è€6ƒì…À‰Ãt©½hÿÿÿ‰|$¸‰D$‰$èd6ƒì ‰t$‰<$èÕ4…À…yÿÿÿ‰\$1É1Ò‰L$ ‰T$Ç$è)6ƒì…À‰Ãu¯éMÿÿÿvU‰åUøSƒì‹]‰T$‰$èw6‹Eøƒì9ˆü@t ¸‹]üɉ$¹ðÿÿÿ‰L$èT6ƒì©tÙ‹ü@1Ò1À‰p@‰D$‰$èî5ƒì1Àë»ë U‰åƒì¡p@…Àt!¡P@…À„„‹ ðû@H£P@…É…à¹p@‰L$‹€ü@‰$è¡4ƒì=p@t-¸‰D$‹ ü@‰ $è³5ƒìÇ$è¬5ƒìÉ¡p@…Àuó‹p@…ÒtÀɶ1Ò1À‰p@‰D$‹ ü@‰ $è5‹ðû@ƒì…Ò„cÿÿÿ‹ ü@…É„Uÿÿÿº‰T$‹E‰$è15ƒìèÉÇ$è%5ƒìé%ÿÿÿt&Ç$°@1À‰D$è5ƒìéÿÿÿU1ɉåS¸ì$‰L$èþÿÿ‰$‰D$è±2‰$‹U ‹E‰T$‰D$è[3‰$è³2Ç\lau¹nch4ºj.lo‰L‰TfÇD g¸``@‰$‰D$è*3Ä$[]ÃU‰åƒì¡ ü@…ÀuÉÉ$èï2ÉÃt&U‰åSƒìÇ$b`@è 3ƒì¹k`@‰L$‰$è3ƒì…À‰Ãtèû2‰$º¤û@‰T$ÿÓƒì¡ ü@…Àt)‹¤û@ºz`@…Ûuº~`@‰T$¹`@‰L$‰$èÈ1‹]üÉÃvU¸‰å]£¨û@ÃU‰åƒì‹¨û@‹E…Òt‰D$¸P@‰D$Ç$`@è$2ÉÉö‰D$1Ò¹P@‰T$ ‰L$Ç$è‰3ƒìÉö¿U‰åƒì(è=2…À‰Â…»‹ ¨û@…É…~Ç$1Ò¸P@‰T$ ¹ ö@‰D$‰L$è13ƒì€= ú@tC¡ ü@…À…pÇ$¹1À‰L$1Ò¹ ú@‰D$¸•`@‰T$ ‰L$‰D$è 3ƒì¡ ü@…Àu"ÉÃÇ$`@º ö@¸P@‰T$‰D$è11뉉$è/1ÉÃt&‰T$1À1ɉD$Eü‰L$¹‰D$1À‰L$ ‰D$Ç$èN1‹ ü@ƒì…Ò… ¹ ö@´&‹ƒÁÿþþþ÷Ð!‰Ð%€€€€tè uÁèƒÁÀ‰Èº ƒØ- ö@f‰ ö@Æ€"ö@‹MüÇ$ ö@‰L$èˆ0‹¨û@…ÒtmÇ$`@¸ ö@¹P@‰D$‰L$èP0‹Uü‰$è­0ƒìé—þÿÿ‹Eü¹š`@‰L$‰$‰D$è…/éCÿÿÿ‰$º ú@¹¦`@‰T$‰L$èf/éqþÿÿÇ$1À¹P@‰D$ º ö@‰L$‰T$èe1ƒì눴&U¸‰åSº ƒì·M‹] ‰D$ ‰T$‰L$¡pü@‰$è0ƒì…ÀtN‰D$‹pü@‰$èþ/ƒì…ÀtO‰$è÷/ƒì…À‰Át>1Ò¶¿¶ ˆB„Àuô‹]ü¸ÉÃÇ$èÆ/ƒìt&¼'‹]ü1ÀÉÉö¼'U1À‰åWü¹V}ÈSƒìLó«·Mº ¾‰t$ ]ȉT$‰L$¡pü@‰$èP/ƒì…Àtb‰D$‹pü@‰$è?/ƒì…Àt,‰$è8/ƒì…À‰Át1Ò¶¼'¶ ˆB„Àuôü‰Þ¿´`@¹ó¦”Ãeô¶Ã[^_]ÃÇ$‰Þ¿´`@èì.ü¹ƒìó¦”Ãeô¶Ã[^_]Ãt&¼'U1À‰åWU؃ìDü‰×¹ó«·M¸‰×‰D$ º ‰T$‰L$¡pü@‰$èq.ƒì…ÀtS‰D$‹pü@‰$è`.ƒì…Àt-‰$èY.ƒì…À‰Át1Ò´&¼'¶ ˆ:B„Àuô‰<$è-‹}üÉÃÇ$è#.ƒì‰<$èø,‹}üÉÃt&¼'Uº¹`@‰åWV¾€Sƒì,‹]‰T$‰$èÎ,9Øtr‰$¸Ë`@¾€‰D$è´,9ØtX‰$¹Ý`@¾€‰L$èš,9Øt>‰$¾ð`@‰t$¾€è€,9Øt$‰$¿û`@¾€‰|$èf,9Øt eô1À[^_]É$¹\‰L$èÇ,‰$x¸\‰D$è«,XÆCÿ‹¤û@ÇEè…Òu~‰|$1ÒMð‰L$¸‰D$ ‰T$‰4$è.ƒì…ÀuFU1Éuì‰T$‹} ‰t$ ‰L$‰|$‰\$‹Eð‰$èð-ƒì‹uð…À”¶ú‰}è‰4$èß-ƒìÆCÿ\‹Eèeô[^_]É|$1ÒMð‰L$¸‰D$ ‰T$‰4$è›-ƒì…Àt‚éTÿÿÿë Uº‰åSƒì‹]‰T$¡pü@‰\$‰$è\,ƒì …Àºÿÿÿÿt‰$¹\‰L$è—+‰Â)Ú‹]ü‰ÐÉÃt&U‰åƒì‰]ø‹]‰uü‹u ‰$èþ*€|ÿ\tfÇ\‰u ‹uü‰]‹]ø‰ì]éu+t&U¹‰åWº1ÀV½ÜûÿÿSìL‹]‰Üûÿÿ‹u‰T$‰Ôûÿÿèûÿÿ‰µØûÿÿ1ö‰D$‰$èj*ë-‰$º õ@‰T$è÷*…À~|¡ ü@…À…¸‰…Üûÿÿ‰t$1Òàûÿÿ‰T$‹•Øûÿÿ1À‰L$1ÉF‰D$‰L$‰|$ ‰\$‰$èT,ƒì …À…è‰$¸ õ@‰D$èˆ*…Àx‘€= õ@…oÿÿÿ‰$¹ ô@‰L$èf*…ÀŽkÿÿÿ‰\$Ç$ ô@è6*Ç$€ó@‹E ‰D$è#*Ç$€ó@è¯)€¸ó@\t º\f‰€ó@‰\$Ç$€ó@è"*¡ ü@‹Ôûÿÿ…À‰  û@„ ÿÿÿ‰$¹€ó@ºa@‰L$‰T$è?)éìþÿÿ‰\$ ‹M ºa@‰T$‰$‰L$è)éËþÿÿeô[^_]ÃU‰åƒì(‰]ô‹]‰}ü‹} ‰uø¡ ü@…ÀuT¡¤û@uð…Àuv¡ ü@…À…/‰t$1Àº‰T$ ‰D$‰\$Ç$€èæ*ƒì…À„Ó‹]ô‹uø‹}ü‰ì]É\$º+a@uð‰T$‰$è†(¡¤û@…Àt—¶¼'‰t$1ɺ‰T$ ‰L$‰\$Ç$€è}*ƒì…À…\ÿÿÿ‰\$‰úʉT$‹Mð‰ $ègýÿÿ‹Eð‰$è\*ƒìö¡û@„&ÿÿÿ¡ ü@…À„Tÿÿÿ‰D$ ¾»‰t$‰\$Ç$Aa@èÍ'é-ÿÿÿ‰|$‰\$‹]ð‰$èýÿÿ‹}ð‰<$èú)ƒì‹]ô‹uø‹}ü‰ì]É\$¹Xa@‰L$‰$è•'é·þÿÿU‰åƒì‰]ô‹]‰uø‹u Cþ‰}üƒø‹}w1‰4$º‰T$èOþÿÿƒût0‰}‹]ô‹uøÇE ‹}ü‰ì]é/þÿÿ‰<$¹‰L$èþÿÿ…Ûu ‹]ô‹uø‹}ü‰ì]Éu‹]ô‹uøÇE ‹}ü‰ì]éòýÿÿ‰öU‰åWVSì<‹u ‹}^þƒû‡¢Ç$pa@º‰T$è½ýÿÿƒþtÇ$˜a@¸‰D$è£ýÿÿv‹ û@…Ò…ƒû‡Ç$Äa@»‰\$ètýÿÿƒþ„Ç$èa@¾‰t$èVýÿÿ‹ û@…Òu|¶¿eô1À[^_]öÇ$˜a@¹‰L$èýÿÿ…ö„sÿÿÿÇ$pa@º‰T$èþüÿÿéYÿÿÿÇ$èa@¸‰D$èäüÿÿ…ö…‹ û@…Òt’‰öÇ$€â1Û‰\$ʵäûÿÿ‰T$ º€ó@‰t$‰T$èÛ'ƒì…À…Pÿÿÿ1Òµèûÿÿ»‰\$Üûÿÿ‰T$‰4$èu%¹1Ò…àûÿÿ‰àûÿÿ¹b@‰D$‰t$‰\$ ‰T$‰L$‹…äûÿÿ‰$è{'ƒì…À…1Ò¶¶„*èûÿÿˆ:B„Àuðö û@t&‰<$è'%€|8ÿ\tfÇ8\‰<$¾b@‰t$è¡%‹½äûÿÿ‰<$è#'ƒìeô¸[^_]ÃÇ$Äa@¹‰L$è®ûÿÿéSþÿÿ‹äûÿÿ‰ $èë&ƒìéSþÿÿvU‰åSƒì¡¨û@‹]…Àt-‰$è$€|ÿ\tfÇ\‰$ºb@‰T$è%ƒÄ[]É$èp$€|ÿ\tfÇ\‰$¹)b@‰L$èê$ƒÄ[]Ãt&U‰åSƒì‹]‹U ‰$‰T$èÇ$‹E€8t‰$è$fÇ;ƒÄ[]Ãt&¼'U‰åSì$1Û‹E€8uB‹ ü@…Òt-…Û¸7b@u¸€½¨üþÿ\t €½©üþÿ:…Ò‰\$Ç$ ð@è„1Û€= ð@…#‹ ü@…Òt-…Û¸7b@u¸€ù •À1Ò€ù •Â…ÐtL¶¿„Ét__p__fmodeP__set_app_typey_cexit{_chdir‚_close¯_findclose°_findfirst³_findnexté_iob _itoa^_onexit__openq_read„_setmode“_statatexitatoi-fclose8fopen9fprintfGfwritezmemsetprintfsignal—strcat˜strchr™strcmp›strcpyŸstrlen strncat¢strncpy£strpbrk¤strrchr¦strstr¨strtokŽShellExecuteAYCreateWindowExA”DispatchMessageAÌEnumWindowsÒFindWindowExA$GetMessageAEGetSystemMetricsTGetWindowLongAZGetWindowRect\GetWindowTextA`GetWindowThreadProcessIdŒKillTimer—LoadImageA®MessageBoxAÐPostQuitMessageôSendMessageASetForegroundWindow+SetTimer4SetWindowPosAShowWindowXTranslateMessagedUpdateWindowADVAPI32.DLLKERNEL32.dll(((((((((((((((((((((((((((((((((((((msvcrt.dll<SHELL32.DLLPPPPPPPPPPPPPPPPPPPPPUSER32.dlløI…R(€ Ø€€øI…R`€x€€¨€À€øI…R8øI…RHøI…RXøI…RhøI…RxøI…R 0€H€`€x€€e¨€fÀ€gØ€hð€øI…RˆøI…R˜øI…R¨øI…R¸øI…RÈøI…RØøI…RèøI…RøøI…RøI…R €øI…R(h¨8(¨%àM(B(0˜8˜ D˜H˜L˜h˜2œ˜s™5H™h°™L(  @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å' ï] ï] å'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê'÷½üÿýÿþÿüÿ÷¿ë'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë)ûéýÿúñö³ö³úïýÿûéí)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Çýÿø¯áÿÿÿÿÿÿ åø¯ýÿ÷ÇÿÿÿÿÿÿÿÿÿÛÛ1‘[U;Âÿ>Àû®3=Û1Û1Û1Û1¯4=>Àû;ÂÿŒ b[Û1Õý{ýÿýÿô++ÿñ33ÿð ÿì98ÿï""ÿó76ÿù ÿíQPÿøÿô))ÿýÿýÿö{ý{þÿþÿö%%ÿ÷##ÿð,,ÿð*)ÿï..ÿ÷%$ÿýÿò,+ÿú ÿô..ÿýÿþÿö{ò%òKµ?o\¡ÿ`žûßQòKòKòKòKãO`ù\¡ÿ²CqòKì%ÿÿÿÿÿÿÿÿÿ÷×ýÿõ™ÛÿÿÿÿÿÿÙõ™ýÿø×%&Éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî7üóýÿùÙõ“õ“ùÙýÿüóð7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð7ù×ýÿýÿýÿýÿøÙð7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ êGó}ó{ ìCÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ €ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ% éuê¡ òÓ òÓë¡ éuÚ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à=ñ½ùÿýÿþÿýÿþÿþÿýÿùÿïÇ á=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔë‘úýþÿýÿþÿýÿýÿþÿþÿýÿýÿýÿúýì‘ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚñ§ýÿýÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿüÿó§ ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëýÿýÿýÿýÿûûðÉãäOäOäðÁûûýÿþÿþÿýÿíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáQûÿýÿýÿýÿöÓáAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å7÷Óýÿþÿþÿûÿ çGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏòÑýÿýÿýÿõÓ Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßõÓýÿýÿýÿñÛ##ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚEüÿýÿþÿùûÞ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ7ùûýÿþÿûÿÞOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ]ÛaÛaÛa™Z¯v‡ÿvˆÿv‡ÿ… ñÜaÛaÛaÛaÛaÛaÛaÛaÛaÛaÛaÛa†~ñvˆÿvˆÿv‡ÿ–_¹ÛaÛaÛaÕ]ÿÿÿÿÿÿý÷ýÿýÿýÿýÿûÿñ33ÿòJJÿõ ÿüÿïÿôÿôÿî ÿüÿö ÿôEEÿö.-ÿüÿò$#ÿóEDÿöÿýÿó0/ÿùÿýÿýÿýÿýÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿõÿîssÿëÿòZYÿüÿ×``ÿã][ÿä[YÿÕhhÿüÿó]\ÿîÿ÷ ÿúÿë‚ÿâWVÿð;:ÿýÿèccÿûÿþÿþÿþÿþÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿôÿò``ÿ÷ÿò\\ÿüÿ×onÿëKJÿêMKÿÔvuÿüÿô\[ÿö ÿýÿýÿêQPÿå]\ÿó#"ÿùÿèÿøÿþÿþÿþÿþÿö÷ÿÿÿÿÿÿý÷þÿþÿþÿþÿùÿö))ÿûÿö('ÿýÿðCCÿö ÿöÿðCCÿýÿö''ÿúÿþÿýÿýÿûÿýÿýÿôÿþÿýÿþÿþÿþÿö÷ÿÿÿÿÿÿòò•ó•ò•Ð(͹Dÿ¹Dÿ¹Dÿà @õò•ò•ò•ò•ò•ò•ò•ò•ò•ò•ò•ò•Ä ?õ¹Dÿ¹Dÿ¸DÿË.×ò•ò•ò•ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞYýÿþÿýÿöõÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×öñýÿýÿüÿ åYÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØóíýÿýÿýÿð­ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒñ­ýÿýÿýÿôí%&Éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ çoüÿýÿþÿýÿð­ÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙð­ýÿýÿýÿýÿ éoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌñÃýÿþÿþÿýÿöçìÖ9×ÖÖ9ëöçýÿýÿþÿýÿñÃÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßõÍýÿþÿþÿýÿýÿûÿùÿùÿûÿýÿþÿþÿþÿýÿ÷Í æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áòÃýÿýÿýÿþÿýÿýÿþÿþÿþÿýÿýÿüÿòà ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔëoõíýÿþÿýÿþÿýÿþÿþÿýÿõí é{ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ ãc îµ òåöÿöÿòÛ îµ çYÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIHìÕ Ô <;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(0` €%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ??è%%ØC&&ØC>>åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ' æ{ ê· çñô÷øÿøÿô÷ èñ ê· æ{Î' Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ !Å ÝGéµõÿüÿýÿýÿýÿþÿþÿþÿþÿýÿüÿöÿ çÍ ÞGÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ é­øÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿøÿ ë­ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜKñëýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿýÿýÿþÿþÿýÿýÿñë àKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ äIõùþÿþÿýÿþÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿ÷ù çIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßKöùýÿýÿýÿýÿýÿýÿýÿýÿõÿòùñïñïóùöÿýÿýÿýÿýÿýÿýÿýÿþÿ÷ù åKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ+ñõýÿýÿýÿþÿýÿýÿûÿïãå™ÑCPQ×'ÿÿÿÿÿÿSSÙ'Ñ? ç…ïãûÿþÿýÿýÿþÿþÿýÿòõÚ+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕêÅýÿþÿþÿþÿýÿýÿöíá‰Ø ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ åq÷íýÿþÿýÿþÿýÿýÿìÅØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ_ùÿþÿýÿýÿýÿýÿòë â/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å/òëýÿýÿýÿýÿýÿúÿß[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ ëãýÿýÿþÿýÿþÿõí ß/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à/õíýÿýÿþÿþÿþÿíå##ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚGûÿýÿýÿýÿýÿùÿ àqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßqúÿýÿýÿýÿýÿùÿÖ]ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ£ ÷ÿ ÷ÿ ÷ÿ ÷ÿ ÷ÿéãÄ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ æã ÷ÿ ÷ÿ ÷ÿ ÷ÿ öÿß±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛAÛÛÛÛÛÚ°Fï§Sÿ§Sÿ§Sÿ§Sÿ§Rÿ¼JïÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÛ¼Iï§Tÿ§Sÿ§Sÿ§Sÿ§Sÿ®HùÚÜÛÛÛÛÈAÿÿÿÿÿÿýsýÿýÿýÿýÿýÿýÿüÿüÿùÿïÿðÿòÿüÿýÿúÿöÿúÿòÿúÿõÿúÿýÿùÿïÿïÿñÿûÿýÿ÷ÿñ ÿñÿ÷ÿüÿüÿõÿô ÿûÿüÿýÿýÿýÿýÿýÿýÿåsÿÿÿÿÿÿýsþÿýÿýÿýÿýÿþÿþÿýÿë99ÿÿèvtÿÿï ÿýÿáÿ燆ÿâÿù¶´ÿâÿä‘ÿàÿýÿñ&%ÿõªªÿðxwÿònmÿö ÿüÿé]\ÿèxwÿé€ÿî=<ÿýÿýÿïdcÿëllÿúÿýÿþÿýÿýÿýÿýÿýÿæsÿÿÿÿÿÿýsþÿþÿþÿþÿþÿþÿþÿüÿñ|{ÿé))ÿúÿîrrÿð,,ÿýÿÞÿàŒÿæjhÿÜIHÿåcaÿÞ˜˜ÿÜÿýÿî('ÿõrqÿûÿþÿýÿ÷ÿö ŸÿäddÿäiiÿéYYÿúÿþÿîmmÿî#$ÿýÿþÿþÿþÿþÿþÿþÿýÿæsÿÿÿÿÿÿýsþÿýÿþÿþÿþÿþÿþÿûÿñz{ÿí!!ÿüÿóefÿï-.ÿýÿÞÿÙ“’ÿê}ÿéÿé‚ÿÖ ÿÜÿýÿï('ÿõrqÿûÿýÿþÿüÿëggÿáihÿãxvÿíLKÿüÿ÷ÿÿëddÿúÿþÿþÿýÿýÿþÿýÿþÿæsÿÿÿÿÿÿýsýÿýÿýÿþÿýÿýÿýÿüÿóyyÿï ÿýÿõeeÿð--ÿþÿàÿ÷ÒÑÿè;;ÿýÿç:9ÿöÖ×ÿßÿýÿð''ÿöqoÿûÿýÿýÿýÿöÿò! ÿòÿ÷ÿýÿûÿîiiÿì--ÿüÿþÿýÿýÿýÿýÿþÿýÿæsÿÿÿÿÿÿþsþÿþÿþÿþÿþÿþÿþÿýÿöÿøÿýÿöÿ÷ÿýÿöÿó$#ÿ÷ÿýÿ÷ÿó##ÿöÿþÿøÿöÿýÿþÿþÿýÿýÿýÿþÿýÿýÿþÿöÿúÿþÿýÿþÿþÿþÿþÿýÿýÿæsÿÿÿÿÿÿòeòßòßòßóßòßòßåýäÿäÿäÿäÿäÿéûòßòßòßòßòßòßòßòßòßòßòßòßòßòßòßñßòßòßéûäÿäÿäÿäÿäÿæýòßòßòßòßòßòßÝeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA ¸±0Òÿ1Òÿ1Ñÿ1Òÿ0ÑÿFÊÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJÅÝ0Òÿ0Ñÿ1Òÿ0Òÿ0ÑÿE ·ÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙuýÿþÿþÿþÿýÿõûÙ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×1÷ñþÿýÿþÿýÿûÿàuÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ ïýýÿýÿýÿýÿýÿïÁ× ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ ðÁýÿýÿýÿýÿýÿòý%&É!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ å•üÿýÿýÿþÿþÿüÿ è¿× ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ× è¿üÿþÿýÿýÿýÿýÿ ã•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏñåýÿýÿýÿþÿýÿüÿîÁÛ1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ1îÁûÿýÿýÿýÿýÿýÿóåØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áWøÿýÿýÿþÿýÿýÿýÿõñ å×/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×/ åôñýÿþÿýÿþÿþÿýÿøÿ áWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ å‘ûÿýÿþÿþÿþÿýÿýÿýÿøû çííŸéŸéŸíŸ çíøûýÿýÿþÿþÿþÿýÿýÿûÿê‘Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì‘ûÿþÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿî‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ç‘ùÿýÿþÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿøÿê‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ åWóåýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿýÿüÿòõ äWÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑê•òýýÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿýÿòýê•Õ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ!ÛðÉóù÷ÿûÿýÿýÿûÿ÷ÿóùðÉ áuÒ!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ10Å%ÓC"!é‘ å‘ å‘çyÓC0/Æ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(@€ Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ11ÄÆE ÞE##éŸã­ã­#"çŸ ßEÇE..ÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ Þq è×íåíÿõÿùÿûÿûÿùÿõÿîÿíå é× ÞqË ÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÓS è¡ñÿùÿýÿýÿþÿþÿýÿþÿþÿþÿþÿþÿýÿýÿùÿòÿäËÔSÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ# âÉõÿüÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿüÿõÿ ãÉÜ#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ ãuñùýÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿüÿñù âuËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ áÅùÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿýÿþÿùÿ äÅÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßêÇûÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿûÿíÇ âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚëÇûÿýÿþÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿüÿíÇ ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ äÅûÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿúÿ çýßýå£ ã• ã•æ£àý èýùÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿûÿ èÅÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ߟúÿýÿýÿýÿþÿþÿýÿýÿýÿüÿóíÝÁØi*+Ù ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×EÜÁõíüÿýÿýÿþÿþÿþÿþÿþÿþÿûÿ áŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Iôýýÿþÿþÿþÿþÿýÿýÿýÿ÷ÿ åÅÓ9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Þ% æ­øÿýÿþÿþÿþÿþÿþÿþÿþÿôýÙIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ È çßüÿþÿýÿþÿýÿþÿþÿýÿó÷ åUÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑ çUô÷ýÿþÿþÿþÿþÿþÿýÿýÿíÉÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ æSøÿýÿýÿýÿþÿýÿþÿþÿò÷ ÞUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßUò÷ýÿþÿýÿýÿþÿþÿýÿøÿÙ}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ äóýÿþÿþÿþÿþÿþÿþÿõÿ áUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ âUöÿýÿýÿýÿþÿþÿþÿýÿ êó##Î ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙKùÿþÿþÿþÿþÿþÿþÿúÿ ã­ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑà­úÿýÿýÿþÿþÿþÿýÿöÿÐqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÅþÿýÿýÿþÿþÿþÿýÿìíÍ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ%ííýÿýÿþÿþÿþÿýÿüÿåÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™b 5 Éß,Ùÿ,Ùÿ,Úÿ,Úÿ,Úÿ,Ùÿ-×ÿO'ÐÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW.ÇÑ,Úÿ,Úÿ,Úÿ,Ùÿ,Úÿ,Ùÿ,Ùÿ9 Èïs+'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ۳ۿܿۿۿۿۿܿÒÏÁ3ÿ¿5ÿ¿5ÿÀ5ÿ¿6ÿ¿6ÿ¿5ÿ¿4ÿÑ *óÛ¿Ü¿Û¿Û¿Ü¿Û¿Û¿Ü¿Û¿Ü¿Û¿Û¿Ü¿Û¿Û¿Û¿Û¿Ü¿Û¿Û¿Û¿Û¿Ü¿Û¿Ñ )ó¿6ÿ¿6ÿ¿6ÿ¿6ÿ¿5ÿ¿6ÿ¿6ÿÁ2ÿÓÏۿܿۿܿۿۿܿϳÿÿÿÿÿÿÿÿÿÿÿÿüïüÿüÿüÿüÿüÿüÿüÿüÿüÿüÿüÿúÿõÿôÿöÿúÿüÿüÿüÿúÿúÿüÿúÿúÿüÿúÿúÿüÿüÿüÿùÿøÿøÿøÿûÿüÿüÿûÿøÿõÿ÷ÿúÿûÿüÿüÿúÿõÿøÿüÿûÿüÿüÿüÿüÿüÿüÿüÿüÿíïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿùÿã65ÿñ““ÿñ•”ÿïŽÿå(&ÿúÿþÿûÿá..ÿæJIÿîÿíYXÿìXWÿîÿãOOÿá32ÿûÿþÿòÿñ€ÿð‹Šÿð‰ˆÿñˆˆÿó..ÿûÿýÿèÿî|zÿÿÿç! ÿýÿþÿýÿì"!ÿñ™˜ÿ÷=>ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿøÅÅÿÞAAÿæÿÞXWÿõ«©ÿïÿþÿúÿÔKKÿÞvvÿÞÿîŸÿò¦¥ÿÛÿÙ~ÿÔQQÿúÿþÿìÿû¹¸ÿâ..ÿëÿìÿö ÿýÿúÿívuÿÜ`_ÿ×ÿÕ??ÿãYXÿùÿýÿþÿéFFÿä„„ÿõÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿõÄÄÿëÿýÿëÿû¹¹ÿêÿþÿúÿÓKKÿØvuÿá_]ÿáa_ÿá]\ÿáWUÿÓ~ÿÔQQÿúÿþÿëÿü¶µÿïÿýÿþÿþÿþÿóÿúœÿê–•ÿòÿ뇇ÿõ‘ÿïÿýÿþÿéGGÿéz{ÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿö¾¿ÿîÿýÿñ ÿú·¶ÿêÿýÿúÿÓJKÿÏzxÿ隘ÿäÿãÿé›ÿÉ„ÿÔQQÿúÿþÿëÿü¶µÿïÿýÿýÿýÿþÿûÿéa_ÿ臆ÿÏ"!ÿßnmÿï}|ÿ÷ÿýÿöÿähiÿ唕ÿòÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿìÿö¾¾ÿïÿýÿò ÿú¶¶ÿêÿýÿúÿÔKKÿç«©ÿè{zÿöÿõÿç{zÿß±±ÿÔQQÿúÿþÿëÿüµ´ÿïÿýÿýÿýÿþÿýÿìÿìVUÿù‚ÿïdbÿé ÿýÿýÿõ ÿêÿí±±ÿõ/.ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿð ÿøššÿóÿýÿõ ÿú””ÿïÿþÿûÿÝ==ÿýÀ¿ÿè#"ÿûÿüÿè! ÿü¼¼ÿÞBCÿûÿþÿðÿû”’ÿóÿýÿþÿþÿþÿýÿýÿûÿöÿûÿýÿþÿþÿþÿñ##ÿî==ÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿþïþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿó ÿüÿþÿûÿó ÿûÿýÿýÿõÿð ÿùÿýÿýÿùÿð ÿõÿýÿþÿûÿó ÿúÿþÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿþÿúÿøÿþÿþÿüÿþÿþÿþÿþÿþÿþÿþÿþÿîïÿÿÿÿÿÿÿÿÿÿÿÿôïôÿôÿôÿõÿõÿôÿôÿóÿñÿñÿñÿñÿñÿñÿñÿñÿòÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿôÿóÿôÿôÿôÿòÿñÿñÿñÿñÿñÿñÿñÿñÿóÿôÿôÿôÿôÿôÿôÿôÿæïÿÿÿÿÿÿÿÿÿÿÿÿå'å)å)æ)ç)æ)å)æ)Ë Eˆvï€ÿ€ÿ€ÿ€ÿÿÿ€ÿ¤$Ùå)æ)å)å)æ)æ)å)å)æ)æ)æ)å)å)æ)æ)æ)å)å)æ)å)å)å)å)å)©(yÙ€ÿ€ÿ€ÿÿ€ÿ€ÿ€ÿ‡wÿ¯Caæ)å)å)æ)æ)å)å)Ù'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ âÙýÿþÿþÿþÿýÿýÿýÿ çÙ((È ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâÑýÿþÿýÿþÿýÿýÿýÿ ëÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ‰ýÿþÿþÿþÿþÿþÿþÿôÿÛaÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Uöõýÿþÿýÿþÿýÿýÿùÿ݉ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ ïÿþÿýÿýÿýÿþÿþÿýÿïÕ Üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜðÕýÿþÿýÿýÿýÿýÿýÿðÿ%&È9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃà¹üÿþÿþÿþÿþÿþÿþÿüÿ æËÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ çËûÿþÿþÿþÿþÿýÿýÿûÿ á¹ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ=ïûýÿþÿþÿþÿþÿþÿþÿûÿ åËÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ åËúÿþÿýÿýÿþÿþÿþÿýÿñûÔ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â…ùÿþÿýÿýÿþÿþÿþÿþÿüÿíÕÛUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙUîÕûÿýÿþÿýÿýÿþÿýÿþÿûÿ â…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌîÍýÿýÿýÿþÿþÿþÿþÿþÿýÿôõ ç§Ì-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ- æ§óõýÿýÿþÿýÿþÿþÿþÿþÿýÿìÍÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏIðóýÿýÿþÿþÿþÿþÿþÿýÿýÿüÿóÿ êÛÕ• !×MÙ+Ô+Ô+Ø+"!ØMÕ• éÛóÿüÿýÿþÿþÿþÿþÿþÿþÿþÿýÿòóØIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßOô÷ýÿýÿþÿþÿþÿþÿþÿýÿýÿýÿýÿùÿöÿõÿóÿóÿôÿöÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿö÷ æOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ åKô÷ýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿö÷ èKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áOðóýÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿòó ãOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒIñÍúÿýÿþÿþÿýÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿúÿïÍÖIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ ç…ñûýÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿýÿýÿýÿñû â±ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ= ä¹òÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿýÿòÿ ä¹Ú=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÓ9سìÙ÷ÿúÿûÿüÿýÿþÿþÿýÿüÿûÿúÿ÷ÿìÙ à‰Ó9ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖCÓ“Ú­íå îÿïÿïÿ îÿ ìÃÛ­Ó“×CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIHì$#ØÒÒ##×<;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿCCëA32ß[%$Ø[ Õ[ Õ[&&Ø[21Þ[BBèAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ11Ä[À‡̇؇ ã‡ëÝéÿèÿçÿçÿèÿèÿêÝ ä‡Ú‡·À‡..Ã[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿЯ׳ Þ³ÜçÛÿ äÿêÿðÿôÿ÷ÿùÿùÿùÿùÿ÷ÿóÿðÿëÿ äÿ ÜÿÜç Þ³Ù³Ò¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÚÇmÓß éßóÿøÿúÿúÿûÿüÿüÿüÿýÿýÿýÿþÿýÿýÿýÿýÿüÿýÿüÿüÿúÿúÿùÿóÿ éßÔßÉmÚ Ó ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃ#Ö;éO áÿëÿòÿøÿûÿýÿýÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿûÿøÿòÿëÿ âÿÚñÖ;Ä#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÖgÕ¿ áÿóÿûÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿýÿôÿ àÿÖ¿ÖgÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆ ã«éÿòÿøÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿóÿéÿ â«Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ؇à÷ñÿúÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿûÿñÿ â÷܇ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜÒe ßëóùûÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿýÿýÿûÿõù ÞëÑe ÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ; åièÿõÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿõÿ èÿ åiË;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐMÔéïÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿúÿðÿØéÔMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔO àßóÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿòÿ åßÚOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛA ãåóÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿýÿüÿõÿ ååÝAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßA æùøÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿýÿûÿêù âAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝA çù÷ÿüÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿþÿýÿøÿêù ßAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚO æåöÿýÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿýÿûÿ æå ßOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒM âßöÿüÿýÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿ÷ÿñÿíÿêÿéÿ æÿ åÿ äÿ äÿ åÿ æÿ éÿëÿîÿòÿ÷ÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ éßÚMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ= Ýéóÿüÿýÿýÿþÿþÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿûÿôÿ ãýÏû&&ÌûEGÙû>?ÞeÛ)Ù)Ø)Ø)Ù)Û)A@àeHHÛû&'ËûÐû åûóýúÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿõÿ ÞéÓ=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÒÿóÿýÿýÿýÿýÿþÿþÿýÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿýÿûÿöÿêÿàïÙÏ""×Ï*+Ù!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓEØÏàï éÿ÷ÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿÙÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÞeïÿúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿüÿøÿïÿëµÔ£('Åoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*)ÅoÑ£íµñÿøÿûÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿìÿ ÛeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËg äõüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿûÿôÿàÿÕ©ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ ßw çÁòÿýÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿøÿ åõÏgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ¿ñÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿüÿøÿìÿÞÍÓK##Ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ü)ÚÍíÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿøÿ Þ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&%ÂÕ‰í÷úÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿ÷ÿ èó å-ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑ å-êóúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿüÿê÷Ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÈgÛÿøÿýÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿüÿòÿ ãÝ Û1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ý1 äÝóÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿøÿî«Ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ãgîÿüÿýÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿüÿôÿ âÕ×AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØA ãÕòÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿðÿÖ¥ !ÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ# é¿ùÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿôÿ áÝØAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×A áÝöÿüÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿ÷ÿßÿÔ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$$Ä ÍÏîÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿøÿ ãóØ1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ1 äó÷ÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿûÿòÿÖÏÎ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ Ýÿõÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿùÿ çÿ ß-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à- éÿüÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿ áÿ'%Î#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØIñÿûÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿïÿÓÍÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑØÍìÿúÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿìÿ*(ÊßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚßûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ åÁØ)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ) ÝÁôÿýÿýÿüÿýÿþÿþÿþÿþÿþÿþÿþÿýÿüÿýÿóÿ×ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ33Çq áóþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿ âÿÏwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕw èÿùÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿùÿ éó%%Õqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɳ èÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿÛµÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ ÞµðÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿôÿÔ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Û³ íÿøÿøÿøÿøÿùÿøÿøÿøÿøÿøÿøÿøÿøÿ õÿ èÿ-'Ö£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ81Ë£Þÿøÿøÿøÿøÿøÿøÿùÿøÿøÿøÿøÿøÿøÿøÿ ôÿÖ¿c5¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™b-_ ¥ËT µÿQºÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ¼ÿQ»ÿQºÿQºÿQºÿT ¶ÿg³ÿ¬aÓ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸nÉ£l!¬ÿQ»ÿQ¼ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQ»ÿQºÿQºÿQ¹ÿT¸ÿc ÿu*‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌoÍÍËÍÍËËËËÌÍÍËÍÍÊ µ3éMÿ¥Rÿ¤Rÿ¥Sÿ¤Sÿ£Sÿ¥Sÿ¥Sÿ¤Sÿ¤Tÿ¤Uÿ¤Tÿ¤Rÿ¥Sÿ¤Sÿ¦Oÿ³ JÿÓ%JÑÌÍÍÍÌÍÌÌÍÍËÍÍËÌÍÌÌÍÌËÍÍËÍÍÌÌÍÌËÍÍËÍÍËÌÍÌÌÍÍÌÍÍËË×)EѲJÿ¤Tÿ¥Vÿ¤Tÿ¤Sÿ¥Sÿ¥Sÿ¤Sÿ¤Sÿ¥Sÿ¤Sÿ¤Tÿ¥Sÿ¤Sÿ¤Sÿ¦Rÿ«Gÿ·1ÃÊÍÌÌÍÌÌÍÍËÍÍËÌÍ̵ oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâßãÿãÿâÿãÿãÿâÿâÿâÿâÿâÿãÿãÿâÿãÿãÿáÿÞÿÛÿÚÿÚÿÚÿÚÿÙÿÚÿÛÿÚÿÚÿÚÿÙÿÚÿÚÿÚÿÚÿÞÿà ÿâÿãÿãÿãÿâÿâÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿâÿãÿãÿãÿãÿãÿâÿâÿàÿÜÿÙÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÚÿÙÿÜÿÞÿáÿãÿâÿãÿäÿãÿâÿãÿãÿâÿãÿãÿâÿãÿãÿâÿÆßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûßûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿúÿúÿúÿúÿúÿúÿúÿùÿøÿøÿ÷ÿøÿúÿúÿúÿûÿûÿûÿûÿûÿûÿúÿùÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿùÿøÿúÿûÿûÿùÿùÿúÿúÿúÿúÿúÿúÿúÿùÿøÿøÿùÿúÿúÿøÿùÿûÿûÿúÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿÛßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿøÿôÿðÿï ÿñ ÿðÿôÿùÿüÿýÿþÿþÿþÿýÿýÿûÿùÿùÿúÿýÿüÿúÿöÿöÿûÿýÿüÿúÿøÿùÿûÿýÿþÿþÿþÿþÿüÿ÷ÿõÿõÿõÿõÿõÿõÿöÿùÿüÿýÿþÿþÿþÿýÿúÿöÿóÿòÿò ÿóÿöÿùÿúÿüÿþÿþÿþÿýÿþÿýÿ÷ÿóÿò ÿôÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿùÿèÿÝÿáFFÿèggÿñutÿðusÿã^]ÿß<;ÿßÿîÿúÿþÿþÿþÿýÿûÿéÿç.-ÿïEDÿãÿõÿôÿê ÿäEDÿäGEÿé ÿõÿõÿàÿíMMÿç21ÿèÿúÿþÿþÿþÿþÿïÿè65ÿâQPÿâQQÿâQPÿâQPÿâQQÿâQPÿåPOÿï00ÿñÿúÿþÿþÿýÿõÿãÿá)'ÿäTRÿñonÿôsrÿè^]ÿä76ÿßÿîÿüÿþÿþÿþÿýÿþÿõÿæÿçYWÿôurÿ÷WWÿõ ÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿîÿÚ$#ÿí——ÿÿÓÒÿýÍÍÿñ³²ÿò¸¶ÿÿÓÒÿúÊÊÿëyxÿÛÿóÿþÿþÿþÿþÿøÿÓÿá„…ÿÿÈÇÿÉÿëÿãÿèFEÿüÍÌÿüÑÏÿè?=ÿæÿêÿÀ ÿÿßàÿäÿÑÿ÷ÿþÿþÿþÿþÿßÿü›™ÿÿßßÿÿÈÇÿÿÂÀÿÿÂÀÿÿÁÂÿÿÁÁÿÿÀ¿ÿÿuuÿì ÿøÿþÿýÿýÿéÿÞA?ÿô¯­ÿÿÆÄÿÿç¡ ÿø¾½ÿú¾½ÿêedÿåÿüÿýÿþÿþÿþÿýÿìÿéigÿþåãÿë³²ÿú‚ÿôÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿàÿò‰ˆÿÿæçÿè——ÿÐ<;ÿÕ('ÿÖ*)ÿÔMLÿîµµÿÿãáÿÛPNÿçÿþÿþÿþÿþÿ÷ÿÌÿÜÿÿÖÕÿÀÿäÿÑ ÿåŽÿÿ¾¼ÿÿÕÓÿé‹ÿÐ ÿãÿµ ÿÿïðÿà›œÿÉÿöÿþÿþÿþÿþÿÛÿü§¦ÿøÑÏÿÜWVÿÖ77ÿÝ76ÿÞ66ÿÞ66ÿâ65ÿí ÿòÿûÿþÿýÿúÿÚÿø³±ÿõ¸·ÿßKIÿÕ#"ÿÔÿÚ65ÿì•”ÿÿÎÍÿó55ÿúÿüÿþÿþÿþÿýÿêÿ犉ÿÿäãÿÂ89ÿéÿôÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿúÿÙ ÿûÛÛÿöÉÉÿÜ/.ÿåÿöÿöÿÙÿÞWVÿþÙØÿûžœÿÜÿþÿþÿþÿýÿ÷ÿËÿÛÿÿÖÖÿ¼ÿÜÿä=<ÿüÆÄÿ×jhÿêwvÿöÁÀÿÝ32ÿÛÿ²ÿÿïðÿà›œÿÈÿöÿþÿþÿþÿýÿÙÿû§¦ÿüÅÃÿë*)ÿëÿ÷ÿùÿùÿùÿûÿýÿýÿþÿüÿôÿè75ÿûßßÿÖmmÿÆÿØ ÿÚ ÿÒ ÿ½%%ÿ¿BAÿÛÿóÿûÿýÿýÿþÿþÿêÿç‹‹ÿÿÛÛÿÑÿûÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿ÷ÿãÿüååÿî­¬ÿ×ÿøÿýÿüÿìÿæ&&ÿù¼»ÿþ»ºÿØÿþÿþÿþÿþÿ÷ÿËÿÛÿÿÖÖÿ¶ÿÓÿìÿúÄÃÿÎ)(ÿÍ#"ÿûÂÀÿêtrÿÔ ÿ®ÿÿïðÿàœ›ÿÈÿöÿþÿþÿþÿüÿØÿû¨§ÿýÅÃÿï))ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿúÿëÿüVUÿúèéÿ触ÿ톅ÿö„„ÿ÷„„ÿó……ÿ興ÿéŽÿôUUÿçÿ÷ÿýÿþÿþÿþÿêÿ狌ÿÿÛÜÿÓÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿâÿüããÿð››ÿßÿýÿþÿýÿôÿèÿõ³³ÿþ¼»ÿ×ÿþÿþÿþÿþÿ÷ÿËÿÛÿÿÑÑÿ¬ÿÇ0.ÿÿº¸ÿâ„‚ÿÚÿÚÿã€ÿü°®ÿÌ,*ÿ¡ÿÿíëÿàœ›ÿÈÿöÿþÿþÿþÿýÿÙÿû§¦ÿýÅÃÿï))ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿûÿïÿóIGÿþìíÿî®­ÿå{zÿíyyÿïyxÿêzyÿæ––ÿùÜÝÿÿ„„ÿçÿøÿýÿþÿþÿþÿêÿ狌ÿÿÛÜÿÓÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüâãÿðššÿßÿýÿþÿüÿ÷ÿêÿö²²ÿþ¼»ÿÖÿþÿþÿþÿþÿ÷ÿËÿÛŽÿÿÐÏÿ¡ÿÆbaÿÿÄÃÿÚDBÿâÿâÿÕDCÿÿÅÄÿÇecÿ•ÿÿèåÿàœ›ÿÈÿöÿþÿþÿþÿþÿÙÿû§¦ÿýÅÃÿï))ÿðÿýÿþÿþÿþÿþÿþÿþÿþÿüÿ÷ÿÞ"ÿþØ×ÿéÿÌÿÓÿ×ÿÌ ÿÕccÿù××ÿéRRÿîÿúÿþÿþÿýÿõÿÙÿàŒÿÿÜÜÿÂÿíÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüâãÿðššÿáÿýÿþÿýÿøÿìÿ÷±²ÿþ¼»ÿÖÿýÿýÿþÿýÿ÷ÿËÿÛÿÿÐÏÿŸ*(ÿó¬«ÿÿàÿòÿðÿãÿôœ›ÿ쮬ÿ”($ÿÿéæÿßœ›ÿÈÿöÿþÿþÿþÿþÿÙÿû¦¦ÿýÅÃÿï))ÿðÿüÿþÿýÿüÿýÿþÿþÿþÿýÿûÿá ÿé~ÿüßÞÿñ–”ÿÐEEÿÄ75ÿâxvÿøÑÐÿü«ªÿßÿ÷ÿüÿýÿüÿüÿèÿêYYÿì·¹ÿÿéêÿÖrrÿóMLÿð ÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿâÿüâãÿðššÿáÿþÿþÿýÿøÿíÿ÷±²ÿþ¼»ÿÖÿýÿýÿþÿýÿ÷ÿËÿÛÿÿÎÌÿ¯SQÿýÔÒÿèSRÿìÿýÿûÿëÿäYWÿüÖÔÿžOLÿÿéçÿàœœÿÈÿöÿþÿþÿþÿþÿÙÿû¦¥ÿýÅÃÿï*(ÿðÿüÿþÿýÿüÿýÿþÿþÿþÿþÿýÿîÿÙÿïwwÿúËÈÿûÕÓÿúÔÓÿúÒÐÿú›™ÿÜ.-ÿåÿüÿýÿýÿüÿüÿç&&ÿø»»ÿúèéÿÿö÷ÿõÖÖÿû£¢ÿøÿùÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿõÿãÿüââÿñ™šÿâÿþÿþÿýÿøÿíÿ÷±²ÿþ»»ÿ×ÿþÿþÿþÿýÿøÿÌÿÜ‘ÿÿÓÑÿð¹¶ÿî®­ÿÏÿóÿýÿýÿòÿÑÿ맦ÿâ©©ÿÿåæÿàœœÿÉÿöÿþÿþÿþÿþÿÚÿû¦¦ÿýÅÂÿï)'ÿðÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿðÿãÿãÿõ.-ÿø32ÿêÿÞÿìÿ÷ÿýÿþÿþÿþÿýÿóÿÖÿߌŒÿÿÛÛÿÁÿéÿøÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿéÿýààÿò—˜ÿäÿþÿþÿýÿøÿñÿù°°ÿþ¸¹ÿÜÿþÿþÿþÿýÿøÿÑÿßÿÿçæÿÿçåÿðihÿÚÿ÷ÿþÿþÿøÿÛÿía`ÿÿÚÚÿÿìíÿãšœÿÏÿ÷ÿþÿþÿþÿþÿÞÿü¥£ÿþÃÁÿô)'ÿñÿüÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿûÿ÷ÿñÿñÿ÷ÿúÿýÿþÿþÿþÿþÿþÿþÿþÿñÿïmlÿÿ¬¬ÿâÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿ÷ÿìÿýÿôbbÿëÿþÿþÿýÿùÿòÿùqrÿùwwÿåÿþÿþÿþÿþÿùÿÜÿç]\ÿúŸŸÿü“’ÿçÿðÿûÿþÿþÿüÿñÿçÿú‹ŠÿúžŸÿëdfÿÝÿùÿþÿþÿþÿþÿçÿökiÿü}|ÿóÿõÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿûÿûÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿøÿëÿè0/ÿïÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿòÿèÿéÿöÿþÿþÿýÿüÿöÿëÿæÿóÿþÿþÿþÿþÿüÿðÿé ÿâÿäÿïÿúÿüÿýÿþÿýÿúÿïÿåÿâÿêÿñÿüÿþÿþÿþÿþÿôÿèÿëÿõÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿüÿóÿîÿøÿþÿþÿþÿþÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþßþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿýÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿþÿýÿýÿýÿýÿýÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿýÿþÿþÿýÿýÿýÿýÿþÿýÿýÿþÿþÿýÿýÿýÿýÿþÿþÿþÿþÿûÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûßûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿûÿúÿúÿûÿüÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿúÿùÿûÿûÿûÿûÿûÿûÿúÿúÿùÿøÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿúÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿûÿÜßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíßîÿíÿíÿîÿíÿîÿíÿîÿîÿîÿîÿíÿíÿîÿíÿíÿêÿè ÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿé ÿëÿìÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿîÿíÿîÿíÿîÿîÿíÿîÿíÿîÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿìÿìÿìÿíÿíÿîÿíÿîÿìÿìÿé ÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿèÿèÿê ÿëÿìÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿíÿîÿíÿíÿîÿÑßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåIæSåSåSæSåSæSåSçSçSçSæSåSåSæSåSåSÃ)­·<ÿµAÿ´Bÿ´Bÿ´Bÿ´BÿµBÿ´Bÿ´Aÿ´BÿµBÿµBÿµBÿ´Bÿ´Bÿµ@ÿ¼<ÿ×<ÁåSæSåSæSåSåSæSåSæSåSåSæSåSæSåSåSæSåSæSæSåSæSåSæSæSåSæSåSæSæSåSæSåSåSæSåSæSåSåSåSåSåSåSåSæSåSæSåSÚ7Á¾;ÿ´Cÿ´Bÿ´Bÿ´BÿµBÿ´Bÿ´Bÿ´Bÿ´Bÿ´Bÿ³Bÿ³Bÿ³Bÿ´Cÿ¶Bÿ¹8ÿÅ&­äSåSæSåSåSæSåSæSåSåSæSåSæSåSåSæSÊIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©CX ¯¿O »ÿLÀÿMÀÿMÀÿLÀÿMÀÿLÀÿM¿ÿMÀÿMÀÿMÀÿNÀÿMÀÿL¿ÿM »ÿc¹ÿªfÜ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·sÏ£h#²ÿL¿ÿL ÀÿMÀÿLÀÿMÀÿLÀÿMÀÿMÀÿLÀÿL ÀÿL ÀÿL¿ÿL¿ÿL ÀÿN ½ÿ^¤ýr*ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ݳñÿýÿýÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿûÿ ìÿ Õ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ))Ì£ãÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿýÿýÿýÿþÿùÿ ݳÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɳ çÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿöÿÛÅ((È-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ à£ðÿýÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿýÿüÿõÿÕ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-,ÅQ áíþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿûÿ åÿÔwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜAîÕùÿýÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿýÿýÿøÿ éí ÓQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙßúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ áÙÒ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ7ÙÙôÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿóÿÔßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ý#ðÿúÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿýÿüÿîÿ äW ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ß æWîÿûÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿýÿýÿýÿýÿëÿ'(ÇÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÛÿõÿþÿþÿþÿýÿýÿýÿýÿýÿþÿþÿþÿþÿþÿþÿùÿ èÿÜQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÜQêÿüÿýÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿþÿýÿúÿ ßÿØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà Í­íÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿ ã÷ÐSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕS å÷÷ÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿúÿðÿØ­Ï ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ;ãÿøÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿôÿ àçÕ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ[ àç÷ÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿöÿÜÿÐ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÞ‰íÿûÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿ ßçÎSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓS áçóÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿïÿ؉ÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ[Úóøÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿôÿ ã÷ÛQÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÛQ â÷óÿûÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿ÷ÿ ãóÏ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØiííùÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿøÿ æÿ áWÑ7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ7 áW çÿøÿüÿýÿþÿþÿþÿþÿýÿýÿþÿþÿþÿýÿýÿþÿþÿþÿüÿëíÜiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ¿ñÿýÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿøÿìÿÞÙÚAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕAÝÙîÿùÿüÿýÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿüÿöÿÜ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌE ãóüÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿòÿ çÕÙ£Ó!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ!Ø£ åÕñÿüÿýÿýÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿ÷ÿ äóÐEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ áAîÿúÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿüÿúÿóÿ åÙ̱ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɱ çÙñÿùÿüÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿûÿìÿ ßAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÏáðÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿüÿ÷ÿîÿ äûÚûÚoÖ)!!Ã);<Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ==Í Â)Ö)ÙoÚû åûíÿ÷ÿüÿýÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿûÿòÿÙáÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ/ ßÏñÿüÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿùÿðÿ ßÿÏÿ%&ÖÁ ÞWÚWØWÕWÔWÔWÕW×WÚW ÞW'&×ÁÏÿ ßÿîÿúÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿôÿ áÏ×/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×9 âÍôÿüÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿûÿ÷ÿóÿñÿîÿìÿëÿéÿéÿéÿéÿêÿìÿîÿñÿóÿ÷ÿúÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿýÿýÿöÿêÍß9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ3 æÛöÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿýÿûÿ çÛ â3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â æñöÿûÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿýÿ÷ÿ êñ ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ â æÛõÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿûÿøÿéÛ ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ3 äÍñÿüÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿþÿûÿôÿ æÍ á3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ9 àÏñÿúÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿûÿðÿ åÏÞ9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ/ÒáñÿýÿþÿþÿþÿþÿþÿþÿþÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿþÿþÿýÿýÿýÿýÿýÿþÿûÿñÿÖáÚ/ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ æA èóóÿûÿýÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿýÿýÿþÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿýÿýÿþÿýÿýÿüÿýÿüÿóÿ åó äAÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔE â¿ðíøÿýÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿýÿüÿùÿñÿÞáÐEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜiÜóóÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿúÿñÿ ßóÚ“ÐOÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ[ æ‰ çÿðÿøÿüÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿüÿöÿñÿ æÿ ã‰Î[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÚ;Ó­ áÿõÿüÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿõÿ áÿÔ­Ù;ÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ ÜÒÑ Þé åÿïÿ÷ÿüÿýÿþÿþÿýÿýÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿýÿýÿþÿþÿþÿüÿ÷ÿîÿ çí ßßÒÑÜÊ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/-Â3$#Ƴ׳í³ïýòÿõÿ÷ÿøÿùÿûÿüÿýÿþÿþÿþÿþÿþÿýÿýÿüÿûÿùÿøÿöÿõÿóÿîýì³سÉQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓƒÙ‡ÚÃÕÿÚÿ äÿìÿóÿ÷ÿûÿýÿþÿþÿýÿûÿ÷ÿòÿìÿ äÿÚÿÕÿÚÃÛ‡ÒƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA@Ì-))Â[Ç[Ö[('è—0/ëÿåÿàÿ áÿ âÿ âÿ áÿàÿäÿ! è³ â[Ö[Ç[)(Ã[?=Ì-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRRñFEê/..Ý/Ò/Ñ/Ó/Ó/Ñ/Ò/,,Ü/<;åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1.6.0.\umlet.jar132http://java.com/downloadAn error occurred while starting the application.This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted.This application requires a Java Runtime EnvironmentThe registry refers to a nonexistent Java Runtime Environment installation or the runtime is corrupted. h  ¨00 ¨%@@ (B€€ (umlet-2015-06-03_UMLet_v13.3/Baselet/.settings/0000755000175000017500000000000012533641120016520 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/.settings/org.eclipse.jdt.core.prefs0000644000175000017500000007552012533641120023513 0ustar benbeneclipse.preferences.version=1 org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning org.eclipse.jdt.core.compiler.problem.deadCode=warning org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=warning org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error org.eclipse.jdt.core.compiler.problem.nullReference=error org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning org.eclipse.jdt.core.compiler.problem.potentialNullReference=error org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.unusedImport=warning org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning org.eclipse.jdt.core.compiler.problem.unusedParameter=warning org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true org.eclipse.jdt.core.formatter.comment.format_block_comments=true org.eclipse.jdt.core.formatter.comment.format_header=true org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false org.eclipse.jdt.core.formatter.comment.format_line_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert org.eclipse.jdt.core.formatter.comment.line_length=9999 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=false org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=false org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=999 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false org.eclipse.jdt.core.formatter.tabulation.char=tab org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true umlet-2015-06-03_UMLet_v13.3/Baselet/.settings/org.eclipse.jdt.ui.prefs0000644000175000017500000001217212533641120023172 0ustar benbencleanup.add_default_serial_version_id=false cleanup.add_generated_serial_version_id=true cleanup.add_missing_annotations=true cleanup.add_missing_deprecated_annotations=true cleanup.add_missing_methods=false cleanup.add_missing_nls_tags=false cleanup.add_missing_override_annotations=true cleanup.add_missing_override_annotations_interface_methods=true cleanup.add_serial_version_id=false cleanup.always_use_blocks=true cleanup.always_use_parentheses_in_expressions=false cleanup.always_use_this_for_non_static_field_access=false cleanup.always_use_this_for_non_static_method_access=false cleanup.convert_to_enhanced_for_loop=true cleanup.correct_indentation=false cleanup.format_source_code=true cleanup.format_source_code_changes_only=false cleanup.make_local_variable_final=true cleanup.make_parameters_final=false cleanup.make_private_fields_final=false cleanup.make_type_abstract_if_missing_method=false cleanup.make_variable_declarations_final=false cleanup.never_use_blocks=false cleanup.never_use_parentheses_in_expressions=true cleanup.organize_imports=true cleanup.qualify_static_field_accesses_with_declaring_class=false cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true cleanup.qualify_static_member_accesses_with_declaring_class=true cleanup.qualify_static_method_accesses_with_declaring_class=false cleanup.remove_private_constructors=true cleanup.remove_trailing_whitespaces=true cleanup.remove_trailing_whitespaces_all=true cleanup.remove_trailing_whitespaces_ignore_empty=false cleanup.remove_unnecessary_casts=true cleanup.remove_unnecessary_nls_tags=true cleanup.remove_unused_imports=false cleanup.remove_unused_local_variables=false cleanup.remove_unused_private_fields=true cleanup.remove_unused_private_members=false cleanup.remove_unused_private_methods=true cleanup.remove_unused_private_types=true cleanup.sort_members=false cleanup.sort_members_all=false cleanup.use_blocks=true cleanup.use_blocks_only_for_return_and_throw=false cleanup.use_parentheses_in_expressions=true cleanup.use_this_for_non_static_field_access=true cleanup.use_this_for_non_static_field_access_only_if_necessary=true cleanup.use_this_for_non_static_method_access=true cleanup.use_this_for_non_static_method_access_only_if_necessary=true cleanup_profile=_Umlet Cleanup cleanup_settings_version=2 eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_Umlet Formatter formatter_settings_version=12 sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true sp_cleanup.add_missing_deprecated_annotations=true sp_cleanup.add_missing_methods=false sp_cleanup.add_missing_nls_tags=false sp_cleanup.add_missing_override_annotations=true sp_cleanup.add_missing_override_annotations_interface_methods=true sp_cleanup.add_serial_version_id=false sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false sp_cleanup.convert_to_enhanced_for_loop=true sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false sp_cleanup.make_variable_declarations_final=true sp_cleanup.never_use_blocks=false sp_cleanup.never_use_parentheses_in_expressions=true sp_cleanup.on_save_use_additional_actions=true sp_cleanup.organize_imports=true sp_cleanup.qualify_static_field_accesses_with_declaring_class=false sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_with_declaring_class=true sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true sp_cleanup.remove_trailing_whitespaces=true sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true sp_cleanup.remove_unnecessary_nls_tags=true sp_cleanup.remove_unused_imports=false sp_cleanup.remove_unused_local_variables=false sp_cleanup.remove_unused_private_fields=true sp_cleanup.remove_unused_private_members=false sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false sp_cleanup.use_blocks=true sp_cleanup.use_blocks_only_for_return_and_throw=false sp_cleanup.use_parentheses_in_expressions=true sp_cleanup.use_this_for_non_static_field_access=true sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=true sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true umlet-2015-06-03_UMLet_v13.3/Baselet/.settings/org.eclipse.core.resources.prefs0000644000175000017500000000013012533641120024725 0ustar benben#Thu Jan 05 15:13:56 CET 2012 eclipse.preferences.version=1 encoding/=UTF-8 umlet-2015-06-03_UMLet_v13.3/Baselet/src/0000755000175000017500000000000012533641120015371 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/0000755000175000017500000000000012533641120016147 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/0000755000175000017500000000000012533641120017566 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/0000755000175000017500000000000012533641120021100 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CustomFunction.java0000644000175000017500000000051212533641120024721 0ustar benbenpackage com.baselet.custom; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CustomFunction { String param_defaults(); } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CustomVariable.java0000644000175000017500000000046012533641120024663 0ustar benbenpackage com.baselet.custom; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface CustomVariable { } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CustomElementPanel.java0000644000175000017500000001165612533641120025520 0ustar benbenpackage com.baselet.custom; import java.awt.Color; import java.awt.Component; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.text.JTextComponent; import com.baselet.control.config.DerivedConfig; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.listener.DividerListener; @SuppressWarnings("serial") public class CustomElementPanel extends JPanel { private final CustomElementAddDiscardListener saveListener = new CustomElementAddDiscardListener(); private final JSplitPane custompanelsplitleft; private final JSplitPane custompanelsplitright; private final JLabel savelabel; private final CustomElementHandler customhandler; private final CustomCodeSyntaxPane customcodepane; private final DrawPanel custompreviewpanel; public CustomElementPanel(CustomElementHandler customhandler) { this.customhandler = customhandler; setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); JPanel custompanel2 = new JPanel(); custompanel2.setLayout(new BoxLayout(custompanel2, BoxLayout.Y_AXIS)); JLabel codelabel = new JLabel(" Code"); codelabel.setFont(DerivedConfig.getPanelHeaderFont()); codelabel.setAlignmentX(Component.LEFT_ALIGNMENT); custompanel2.add(codelabel); customcodepane = customhandler.getCodePane(); JPanel codePanel = customcodepane.getPanel(); codePanel.setAlignmentX(Component.LEFT_ALIGNMENT); custompanel2.add(codePanel); JPanel custompanel3 = new JPanel(); custompanel3.setLayout(new BoxLayout(custompanel3, BoxLayout.Y_AXIS)); DiagramHandler d = customhandler.getPreviewHandler(); custompreviewpanel = d.getDrawPanel(); custompreviewpanel.getScrollPane().setAlignmentX(Component.LEFT_ALIGNMENT); JLabel previewlabel = new JLabel(" Preview"); previewlabel.setFont(DerivedConfig.getPanelHeaderFont()); previewlabel.setAlignmentX(Component.LEFT_ALIGNMENT); JPanel labelpanel = new JPanel(); labelpanel.setLayout(new BoxLayout(labelpanel, BoxLayout.Y_AXIS)); labelpanel.setAlignmentX(Component.LEFT_ALIGNMENT); savelabel = new JLabel(" Add to diagram and close editor") { private boolean enabled = false; @Override public void setEnabled(boolean en) { if (!enabled && en) { enabled = en; addMouseListener(saveListener); } else if (enabled && !en) { enabled = en; removeMouseListener(saveListener); } } }; savelabel.setFont(DerivedConfig.getPanelHeaderFont()); savelabel.setAlignmentX(Component.RIGHT_ALIGNMENT); savelabel.setEnabled(true); JLabel discardlabel = new JLabel("Discard and close editor"); discardlabel.setFont(DerivedConfig.getPanelHeaderFont()); discardlabel.setAlignmentX(Component.RIGHT_ALIGNMENT); discardlabel.addMouseListener(saveListener); custompanel3.add(previewlabel); custompanel3.add(custompreviewpanel.getScrollPane()); custompanel3.add(labelpanel); custompanel3.addComponentListener(new DividerListener()); labelpanel.add(Box.createHorizontalGlue()); labelpanel.add(savelabel); labelpanel.add(discardlabel); custompanelsplitleft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, null, custompanel2); custompanelsplitleft.setDividerSize(5); custompanelsplitleft.setResizeWeight(0); custompanelsplitleft.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 0)); custompanelsplitright = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, custompanelsplitleft, custompanel3); custompanelsplitright.setDividerSize(5); custompanelsplitright.setResizeWeight(1); custompanelsplitright.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 0)); this.add(custompanelsplitright); } public void setCustomElementSaveable(boolean enable) { customhandler.getPreviewHandler().getDrawPanel().setEnabled(enable); savelabel.setEnabled(enable); if (enable) { savelabel.setForeground(Color.black); } else { savelabel.setForeground(Color.gray); } } // specifies if the custom element is opened as new element or as edited element public void setCustomElementIsNew(boolean isnew) { if (isnew) { savelabel.setText("Add to diagram and close editor"); } else { savelabel.setText("Update in diagram and close editor"); } } public JSplitPane getLeftSplit() { return custompanelsplitleft; } public JSplitPane getRightSplit() { return custompanelsplitright; } public JTextComponent getTextPane() { return customcodepane.getTextComponent(); } @Override public void repaint() { super.repaint(); if (customcodepane != null) { customcodepane.repaint(); } if (custompreviewpanel != null && custompreviewpanel.getScrollPane() != null) { custompreviewpanel.getScrollPane().repaint(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CompileError.java0000644000175000017500000000325712533641120024354 0ustar benbenpackage com.baselet.custom; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.baselet.control.constants.Constants; public class CompileError { // Pattern for error messages from custom element compiler (1. Group = LineNr, 2. Group = line, 3. Group = error) private static final Pattern error_pattern = Pattern.compile(".*ERROR.*at line ([0-9]+).*\\n(.*)\\n.*\\n(.*)"); // EXAMPLE: // 1. ERROR in C:\Users\Andi\AppData\Local\Temp\CustomElementImpl.java (at line 27) // int y=textHeight(); // ^^^^^^^^^^^^ // Type mismatch: cannot convert from float to int private final int lineNr; private final String line; private final String error; public static List getListFromString(String errorString, int beforecodelines) { List returnList = new ArrayList(); String[] splitErrors = errorString.replaceAll("\r\n", Constants.NEWLINE).split(Constants.NEWLINE + "----------" + Constants.NEWLINE); for (String error : splitErrors) { Matcher m = error_pattern.matcher(error); if (m.find()) { Integer newLineNr = Integer.parseInt(m.group(1)) - beforecodelines; String newLine = m.group(2); String newError = m.group(3); returnList.add(new CompileError(newLineNr, newLine, newError)); } } return returnList; } private CompileError(int lineNr, String line, String error) { super(); this.lineNr = lineNr; this.line = line; this.error = error; } public int getLineNr() { return lineNr; } public String getLine() { return line; } public String getError() { return error; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CustomElementAddDiscardListener.java0000644000175000017500000000240212533641120030136 0ustar benbenpackage com.baselet.custom; import java.awt.Color; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JLabel; import com.baselet.control.constants.Constants; import com.baselet.gui.CurrentGui; public class CustomElementAddDiscardListener implements MouseListener { @Override public void mouseClicked(MouseEvent me) { } @Override public void mouseEntered(MouseEvent me) { CurrentGui.getInstance().getGui().setCursor(Constants.HAND_CURSOR); JLabel label = (JLabel) me.getComponent(); label.setForeground(Color.blue); } @Override public void mouseExited(MouseEvent me) { CurrentGui.getInstance().getGui().setCursor(Constants.DEFAULT_CURSOR); JLabel label = (JLabel) me.getComponent(); label.setForeground(Color.black); } @Override public void mousePressed(MouseEvent me) { JLabel label = (JLabel) me.getComponent(); if (!label.getText().startsWith("Discard")) { CurrentGui.getInstance().getGui().getCurrentCustomHandler().saveEntity(); } if (CurrentGui.getInstance().getGui().getCurrentCustomHandler().closeEntity()) { CurrentGui.getInstance().getGui().setCustomPanelEnabled(false); } } @Override public void mouseReleased(MouseEvent me) { } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/custom/CustomCodeSyntaxPane.java0000644000175000017500000000604212533641120026025 0ustar benbenpackage com.baselet.custom; import java.awt.BorderLayout; import java.lang.reflect.Method; import java.util.ArrayList; import javax.swing.JPanel; import javax.swing.ScrollPaneConstants; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.autocomplete.BasicCompletion; import org.fife.ui.autocomplete.DefaultCompletionProvider; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.RTextScrollPane; import com.baselet.control.config.DerivedConfig; import com.baselet.element.old.custom.CustomElement; public class CustomCodeSyntaxPane { private final JPanel panel; private final RTextScrollPane scrollPane; private final RSyntaxTextArea textArea; private final DefaultCompletionProvider provider = new DefaultCompletionProvider(); public CustomCodeSyntaxPane() { panel = new JPanel(new BorderLayout()); textArea = new RSyntaxTextArea(); textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); textArea.setAntiAliasingEnabled(true); textArea.setCodeFoldingEnabled(true); textArea.setFont(DerivedConfig.getPanelContentFont()); // setup autocompletion for (String word : getAutocompletionStrings()) { provider.addCompletion(new BasicCompletion(provider, word)); } new AutoCompletion(provider).install(textArea); scrollPane = new RTextScrollPane(textArea); scrollPane.setFoldIndicatorEnabled(true); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); panel.add(scrollPane); textArea.getDocument().putProperty(PlainDocument.tabSizeAttribute, 3); // Reduce tab size } public String getText() { return textArea.getText(); } public JTextComponent getTextComponent() { return textArea; } public JPanel getPanel() { return panel; } public void setCode(String text) { textArea.setText(text); } private String getStringForCustomElementMethod(Method m) { CustomFunction cm = m.getAnnotation(CustomFunction.class); StringBuilder sb = new StringBuilder(""); sb.append(m.getName()).append("("); String[] params = cm.param_defaults().split(","); Class[] types = m.getParameterTypes(); for (int i = 0; i < params.length && i < types.length; i++) { if (i != 0) { sb.append(", "); } sb.append(types[i].getSimpleName()).append(" ").append(params[i].trim()); } return sb.append(");").toString(); } private ArrayList getAutocompletionStrings() { ArrayList descriptors = new ArrayList(); for (Method m : CustomElement.class.getDeclaredMethods()) { if (m.isAnnotationPresent(CustomFunction.class)) { descriptors.add(getStringForCustomElementMethod(m)); } } return descriptors; } public void repaint() { if (scrollPane != null) { scrollPane.repaint(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/0000755000175000017500000000000012533641120021217 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/ElementFactorySwing.java0000644000175000017500000000552112533641120026016 0ustar benbenpackage com.baselet.element; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import com.baselet.control.Main; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.DiagramHandler; import com.baselet.element.elementnew.ElementFactory; import com.baselet.element.interfaces.DrawHandlerInterface; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.OldGridElement; import com.baselet.element.relation.Relation; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.Stickables; public class ElementFactorySwing extends ElementFactory { /** * uses no reflection, to avoid complications with GWT */ public static NewGridElement create(ElementId id, Rectangle bounds, String panelAttributes, String additionalAttributes, DiagramHandler handler) { final NewGridElement returnObj = createAssociatedGridElement(id); ComponentSwing component = new ComponentSwing(returnObj); DrawHandlerInterface panel = new DrawHandlerInterface() { @Override public void updatePropertyPanel() { Main.getHandlerForElement(returnObj).getDrawPanel().getSelector().updateSelectorInformation(); // update the property panel to display changed attributes } @Override public int getGridSize() { return Main.getHandlerForElement(returnObj).getGridSize(); } @Override public boolean isInitialized() { return Main.getHandlerForElement(returnObj) != null; } @Override public StickableMap getStickableMap() { DiagramHandler h = Main.getHandlerForElement(returnObj); List stickables = h.getDrawPanel().getStickables(Collections. emptyList()); return Stickables.getStickingPointsWhichAreConnectedToStickingPolygon(returnObj.generateStickingBorder(), stickables); } }; returnObj.init(bounds, panelAttributes, additionalAttributes, component, panel); handler.setHandlerAndInitListeners(returnObj); return returnObj; } public static GridElement createCopy(GridElement src) { if (src instanceof OldGridElement) { return ((OldGridElement) src).cloneFromMe(); } else { return create(src.getId(), src.getRectangle().copy(), src.getPanelAttributes(), src.getAdditionalAttributes(), Main.getHandlerForElement(src)); } } public static GridElement createCopy(GridElement src, DiagramHandler handler) { GridElement returnElement = createCopy(src); handler.setHandlerAndInitListeners(returnElement); return returnElement; } public static List createCopy(Collection src) { List list = new ArrayList(); for (GridElement o : src) { list.add(createCopy(o)); } return list; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/0000755000175000017500000000000012533641120021775 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/0000755000175000017500000000000012533641120023307 5ustar benben././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElementCompileTask.javaumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElementCompileTask.jav0000644000175000017500000000053412533641120030733 0ustar benbenpackage com.baselet.element.old.custom; import java.util.TimerTask; public class CustomElementCompileTask extends TimerTask { private CustomElementHandler handler; public CustomElementCompileTask(CustomElementHandler handler) { this.handler = handler; } @Override public void run() { handler.runCompilation(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElementWithErrors.java0000644000175000017500000000324212533641120030770 0ustar benbenpackage com.baselet.element.old.custom; import java.util.List; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.custom.CompileError; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.swing.DrawHandlerSwing; import com.baselet.element.interfaces.GridElement; public class CustomElementWithErrors extends CustomElement { private static final long serialVersionUID = 1L; private List errors; public CustomElementWithErrors() { super(); } public CustomElementWithErrors(List errors) { super(); this.errors = errors; } @Override public void paint() { DrawHandlerSwing drawer = new DrawHandlerSwing(this); drawer.setGraphics(g2); drawer.setHandler(Main.getHandlerForElement(this)); drawer.setForegroundColor(ColorOwn.RED); drawer.drawRectangle(0, 0, getRealSize().width, getRealSize().height); if (errors != null) { double y = textHeight(); double x = Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(false); drawer.print("Custom Element With Errors:", x, (int) y, AlignHorizontal.LEFT); y += textHeight(); for (CompileError error : errors) { drawer.print(error.getLineNr() + ": " + error.getError(), x, (int) y, AlignHorizontal.LEFT); y += textHeight(); } } drawer.drawAll(Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)); } @Override public final GridElement cloneFromMe() { CustomElementWithErrors e = (CustomElementWithErrors) super.cloneFromMe(); e.setCode(getCode()); e.errors = errors; return e; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/FileClassLoader.java0000644000175000017500000000224612533641120027152 0ustar benbenpackage com.baselet.element.old.custom; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import com.baselet.control.util.Path; import com.baselet.control.util.Utils; public class FileClassLoader extends ClassLoader { public FileClassLoader() { super(); } public FileClassLoader(ClassLoader parent) { super(parent); } @Override protected Class findClass(String className) throws ClassNotFoundException { Class c = null; try { byte[] data = loadClassData(className); c = defineClass(className, data, 0, data.length); if (c == null) { throw new ClassNotFoundException(className); } } catch (IOException e) { throw new ClassNotFoundException(className, e); } return c; } private byte[] loadClassData(String className) throws IOException { File f = new File(Path.temp() + className + ".class"); byte[] buff = new byte[(int) f.length()]; FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); dis.readFully(buff); dis.close(); Utils.safeDeleteFile(f, false); return buff; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElementHandler.java0000644000175000017500000001703212533641120030237 0ustar benbenpackage com.baselet.element.old.custom; import java.util.Iterator; import java.util.Timer; import java.util.TimerTask; import com.baselet.control.Main; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.custom.CustomCodeSyntaxPane; import com.baselet.custom.CustomElementPanel; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.CustomPreviewHandler; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.ElementFactorySwing; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; public class CustomElementHandler { private final Timer timer; private final CustomCodeSyntaxPane codepane; private final CustomPreviewHandler preview; private GridElement editedEntity; private GridElement originalElement; private TimerTask compiletask; private boolean changed; private final ErrorHandler errorhandler; private boolean compilation_running; private final CustomElementPanel panel; boolean keypressed; private String old_text; public CustomElementHandler() { codepane = new CustomCodeSyntaxPane(); errorhandler = new ErrorHandler(codepane); codepane.getTextComponent().addMouseMotionListener(errorhandler); preview = new CustomPreviewHandler(); timer = new Timer("customElementTimer", true); changed = false; compilation_running = false; old_text = null; panel = new CustomElementPanel(this); } public CustomElementPanel getPanel() { return panel; } public void newEntity() { this.newEntity("Default"); } public void newEntity(String template) { preview.closePreview(); originalElement = null; editedEntity = CustomElementCompiler.getInstance().genEntityFromTemplate(template, errorhandler); if (editedEntity instanceof CustomElement) { codepane.setCode(((CustomElement) editedEntity).getCode()); } else { codepane.setCode(""); } editedEntity.setPanelAttributes("// Modify the text below and" + Constants.NEWLINE + "// observe the element preview." + Constants.NEWLINE + Constants.NEWLINE + "Hello, World! " + Constants.NEWLINE + "Enjoy " + Program.getInstance().getProgramName() + "!"); editedEntity.setRectangle(new Rectangle(20, 20, 200, 200)); updatePreview(editedEntity); getPreviewHandler().getDrawPanel().getSelector().select(editedEntity); setChanged(false); start(); } public void editEntity(CustomElement e) { preview.closePreview(); originalElement = e; editedEntity = e.cloneFromMe(); editedEntity.setLocation(20, 20); codepane.setCode(e.getCode()); updatePreview(editedEntity); getPreviewHandler().getDrawPanel().getSelector().select(editedEntity); setChanged(false); start(); } public void saveEntity() { GridElement e = CustomElementCompiler.getInstance().genEntity(codepane.getText(), errorhandler); editedEntity = e; updatePreview(e); // update preview panel to set the entities bounds... updateElement(e); setChanged(false); } public boolean closeEntity() { if (changed) { setChanged(false); } stop(); preview.closePreview(); preview.getDrawPanel().getSelector().deselectAll(); // clear controller before editing new custom element CurrentDiagram.getInstance().getDiagramHandler().getController().clear(); DrawPanel dia = CurrentGui.getInstance().getGui().getCurrentDiagram(); if (dia != null) { dia.getSelector().updateSelectorInformation(); } else { Main.getInstance().setPropertyPanelToGridElement(null); } return true; } public CustomPreviewHandler getPreviewHandler() { return preview; } public CustomCodeSyntaxPane getCodePane() { return codepane; } private void updatePreview(GridElement e) { if (e != null) { Iterator iter = preview.getDrawPanel().getGridElements().iterator(); if (iter.hasNext()) { GridElement element = iter.next(); e.setRectangle(element.getRectangle()); e.setPanelAttributes(element.getPanelAttributes()); preview.getDrawPanel().removeElement(element); } preview.setHandlerAndInitListeners(e); preview.getDrawPanel().addElement(e); e.repaint(); } } // starts the task private void start() { compiletask = new CustomElementCompileTask(this); timer.schedule(compiletask, Constants.CUSTOM_ELEMENT_COMPILE_INTERVAL, Constants.CUSTOM_ELEMENT_COMPILE_INTERVAL); } // stops the task private void stop() { if (compiletask != null) { compiletask.cancel(); } } // runs compilation every 1 seconds and updates gui/errors... protected void runCompilation() { if (!compilation_running && !keypressed) // prevent 2 compilations to run at the same time (if compilation takes more then 1sec) { compilation_running = true; String txt = codepane.getText(); if (!txt.equals(old_text)) { setChanged(true); errorhandler.clearErrors(); old_text = txt; editedEntity = CustomElementCompiler.getInstance().genEntity(txt, errorhandler); panel.setCustomElementSaveable(true); updatePreview(editedEntity); } compilation_running = false; } keypressed = false; } private void setChanged(boolean changed) { this.changed = changed; CurrentGui.getInstance().getGui().setCustomElementChanged(this, changed); } // reloads the element on all open panels and adds it to the custom element panel if not already there. private void updateElement(GridElement element) { // if a new element has been created add it to current diagram if (originalElement == null) { DiagramHandler current = null; DrawPanel c = CurrentGui.getInstance().getGui().getCurrentDiagram(); if (c == null) { Main.getInstance().doNew(); current = CurrentGui.getInstance().getGui().getCurrentDiagram().getHandler(); } else { current = c.getHandler(); } // set location for element int x = 10, y = 10; for (GridElement e : current.getDrawPanel().getGridElements()) { if (e.getRectangle().y + e.getRectangle().height + 10 > y) { y = e.getRectangle().y + e.getRectangle().height + 10; } } Rectangle bounds = new Rectangle(x, y, element.getRectangle().width, element.getRectangle().height); addElementToDiagram(element, current, true, bounds, element.getPanelAttributes()); } else { // replace edited element (and ONLY edited element) Main.getHandlerForElement(originalElement).getDrawPanel().removeElement(originalElement); addElementToDiagram(element, Main.getHandlerForElement(originalElement), true, originalElement.getRectangle(), originalElement.getPanelAttributes()); } } private void addElementToDiagram(GridElement e, DiagramHandler d, boolean setchanged, Rectangle bounds, String state) { // TODO bug if custom elements get inserted in zoomed drawpanel // the zoom to 100% bugfix works for inserting new elements but editing old elements with zoom will not work anymore // We must zoom to the defaultGridsize before execution // int oldZoom = d.getGridSize(); // d.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); GridElement e2 = ElementFactorySwing.createCopy(e, d); e2.setPanelAttributes(state); e2.setRectangle(bounds); d.getDrawPanel().addElement(e2); if (setchanged) { d.setChanged(true); } // And zoom back to the oldGridsize after execution // d.setGridAndZoom(oldZoom, false); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/StyleShape.java0000644000175000017500000000530112533641120026232 0ustar benbenpackage com.baselet.element.old.custom; import java.awt.Color; import java.awt.Shape; import com.baselet.control.enums.LineType; /** * Extended shape which supports the stroketype and the line thickness */ public class StyleShape { private Shape shape; private LineType lineType; private int lineThickness; private Color fgColor; private Color bgColor; private float alpha; public StyleShape(Shape shape, LineType lineType, int lineThickness, Color fgColor, Color bgColor, float alpha) { super(); this.shape = shape; this.lineType = lineType; this.lineThickness = lineThickness; this.fgColor = fgColor; this.bgColor = bgColor; this.alpha = alpha; } public Shape getShape() { return shape; } public LineType getLineType() { return lineType; } public int getLineThickness() { return lineThickness; } public Color getFgColor() { return fgColor; } public Color getBgColor() { return bgColor; } public float getAlpha() { return alpha; } public void setShape(Shape shape) { this.shape = shape; } public void setLineType(LineType lineType) { this.lineType = lineType; } public void setLineThickness(int lineThickness) { this.lineThickness = lineThickness; } public void setFgColor(Color fgColor) { this.fgColor = fgColor; } public void setBgColor(Color bgColor) { this.bgColor = bgColor; } public void setAlpha(float alpha) { this.alpha = alpha; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Float.floatToIntBits(alpha); result = prime * result + (bgColor == null ? 0 : bgColor.hashCode()); result = prime * result + (fgColor == null ? 0 : fgColor.hashCode()); result = prime * result + lineThickness; result = prime * result + (shape == null ? 0 : shape.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } StyleShape other = (StyleShape) obj; if (Float.floatToIntBits(alpha) != Float.floatToIntBits(other.alpha)) { return false; } if (bgColor == null) { if (other.bgColor != null) { return false; } } else if (!bgColor.equals(other.bgColor)) { return false; } if (fgColor == null) { if (other.fgColor != null) { return false; } } else if (!fgColor.equals(other.fgColor)) { return false; } if (lineThickness != other.lineThickness) { return false; } if (lineType != other.lineType) { return false; } if (shape == null) { if (other.shape != null) { return false; } } else if (!shape.equals(other.shape)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/ErrorHandler.java0000644000175000017500000000342312533641120026543 0ustar benbenpackage com.baselet.element.old.custom; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.HashMap; import java.util.List; import com.baselet.custom.CompileError; import com.baselet.custom.CustomCodeSyntaxPane; public class ErrorHandler implements MouseMotionListener { private CustomCodeSyntaxPane codepane; private HashMap errors; public ErrorHandler(CustomCodeSyntaxPane codepane) { this.codepane = codepane; errors = new HashMap(); } /******************** ERROR HANDLING *************************/ @Override public void mouseDragged(MouseEvent arg0) { } @Override public void mouseMoved(MouseEvent me) { int line = Math.round(me.getY() / (float) codepane.getTextComponent().getFontMetrics(codepane.getTextComponent().getFont()).getHeight()); if (errors.get(line) != null) { codepane.getTextComponent().setToolTipText(errors.get(line)); } else { codepane.getTextComponent().setToolTipText(null); } } protected void clearErrors() { errors.clear(); // TODO CUSTOM ELEMENTS REFACTORING // this.codepane.getStyledDocument().setCharacterAttributes(0, this.codepane.getText().length(), this.codepane.getStyledDocument().getStyle("default"), true); } @SuppressWarnings("unused") protected void addError(Integer line, String error, int from, int length) { errors.put(line, error); // TODO CUSTOM ELEMENTS REFACTORING // this.codepane.getStyledDocument().setCharacterAttributes(from, length, this.codepane.getStyledDocument().getStyle("error"), true); } public void addErrors(List compileErrors) { for (CompileError error : compileErrors) { addError(error.getLineNr(), error.getError(), 0, 0); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElementCompiler.java0000644000175000017500000001504112533641120030432 0ustar benbenpackage com.baselet.element.old.custom; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.log4j.Logger; import com.baselet.control.config.Config; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.Constants; import com.baselet.control.util.Path; import com.baselet.custom.CompileError; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.element.ErrorOccurred; public class CustomElementCompiler { private static final Logger log = Logger.getLogger(CustomElementCompiler.class); private static CustomElementCompiler compiler; private static final String templatefile = "Default.java"; private final String template; private final Pattern template_pattern; private Matcher template_match; private final String classname; private int beforecodelines; // lines of code before the custom code begins (for error processing) private List compilation_errors; private boolean global_error; public static CustomElementCompiler getInstance() { if (compiler == null) { compiler = new CustomElementCompiler(); } return compiler; } private final File sourcefile; private CustomElementCompiler() { global_error = false; compilation_errors = new ArrayList(); beforecodelines = 0; template_pattern = Pattern.compile("(.*)(/\\*\\*\\*\\*CUSTOM_CODE START\\*\\*\\*\\*/\n)(.*)(\n\\s\\s/\\*\\*\\*\\*CUSTOM_CODE END\\*\\*\\*\\*/)(.*)", Pattern.DOTALL); template = loadJavaSource(new File(Path.customElements() + templatefile)); if (!"".equals(template)) { template_match = template_pattern.matcher(template); try { if (template_match.matches()) { beforecodelines = template_match.group(1).split(Constants.NEWLINE).length; } else { global_error = true; } } catch (Exception ex) { ex.printStackTrace(); } } else { global_error = true; } classname = Constants.CUSTOM_ELEMENT_CLASSNAME; sourcefile = new File(Path.temp() + classname + ".java"); sourcefile.deleteOnExit(); new File(Path.temp() + classname + ".class").deleteOnExit(); } // compiles the element and returns the new entity if successful private CustomElement compile(String code) { saveJavaSource(code); CustomElement entity = null; compilation_errors.clear(); try { StringWriter compilerErrorMessageSW = new StringWriter(); // catch compiler messages PrintWriter compilerErrorMessagePW = new PrintWriter(compilerErrorMessageSW); String path = Path.executable(); String javaVersion = "-\"1.6\""; // custom elements use Java6 (previously SystemInfo.JAVA_VERSION, but this only works if the compiler.jar supports the system java version which is not guaranteed) String classpath = "-classpath \"" + path + "\"" + File.pathSeparator + "\"" + path + "bin/\""; String sourcefile = "\"" + this.sourcefile.getAbsolutePath() + "\""; // Compiler Information at http://dev.eclipse.org/viewcvs/index.cgi/jdt-core-home/howto/batch%20compile/batchCompile.html?revision=1.7 @SuppressWarnings("deprecation") boolean compilationSuccessful = org.eclipse.jdt.internal.compiler.batch.Main.compile( javaVersion + " " + classpath + " " + sourcefile, new PrintWriter(System.out), compilerErrorMessagePW); if (compilationSuccessful) { FileClassLoader fcl = new FileClassLoader(Thread.currentThread().getContextClassLoader()); Class c = fcl.findClass(classname); // load class by type name if (c != null) { entity = (CustomElement) c.newInstance(); } } else { compilation_errors = CompileError.getListFromString(compilerErrorMessageSW.toString(), beforecodelines); } } catch (Exception e) { log.error(null, e); } if (entity == null) { entity = new CustomElementWithErrors(compilation_errors); } return entity; } // loads the source from a file private String loadJavaSource(File sourceFile) { // LME3 StringBuilder sb = new StringBuilder(""); if (sourceFile != null && sourceFile.getName().endsWith(".java")) { try { BufferedReader br = new BufferedReader(new FileReader(sourceFile)); String line; while ((line = br.readLine()) != null) { sb.append(line).append(Constants.NEWLINE); } br.close(); } catch (Exception e) { log.error(null, e); } } return sb.toString().replaceAll("\r\n", Constants.NEWLINE); } // saves the source to a file private void saveJavaSource(String code) { // LME3 BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(sourcefile, false)); bw.write(parseCodeIntoTemplate(code)); bw.flush(); } catch (IOException e) { log.error(null, e); } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } private String parseCodeFromTemplate(String template) { Matcher m = template_pattern.matcher(template); if (m.matches()) { return m.group(3); } else { return ""; } } private String parseCodeIntoTemplate(String code) { return template_match.group(1).replaceFirst("", classname) + template_match.group(2) + code + template_match.group(4) + template_match.group(5); } public GridElement genEntity(String code, ErrorHandler errorhandler) { if (!Config.getInstance().isEnable_custom_elements()) { String errorMessage = "Custom Elements are disabled\nEnabled them in the Options\nOnly open them from trusted\nsources to avoid malicious code execution!"; if (SharedConfig.getInstance().isDev_mode()) { errorMessage += "\n------------------------------------\n" + code; } return new ErrorOccurred(errorMessage); } if (global_error) { return new ErrorOccurred(); } if (code == null) { code = parseCodeFromTemplate(template); } CustomElement element = compile(code); if (errorhandler != null) { errorhandler.addErrors(compilation_errors); } element.setCode(code); return element; } public GridElement genEntity(String code) { return this.genEntity(code, null); } public GridElement genEntityFromTemplate(String templatename, ErrorHandler errorhandler) { String template = loadJavaSource(new File(Path.customElements() + templatename + ".java")); if (!"".equals(template)) { return this.genEntity(parseCodeFromTemplate(template), errorhandler); } return null; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/custom/CustomElement.java0000644000175000017500000004637212533641120026752 0ustar benbenpackage com.baselet.element.old.custom; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Arc2D; import java.awt.geom.CubicCurve2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.QuadCurve2D; import java.awt.geom.RoundRectangle2D; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.custom.CustomFunction; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public abstract class CustomElement extends OldGridElement { private static class Text { private final String text; private final int x, y; private final AlignHorizontal align; private Integer fixedSize; private Text(String text, int x, int y, AlignHorizontal align) { this.text = text; this.x = x; this.y = y; this.align = align; } private Text(String text, int x, int y, AlignHorizontal align, Integer fixedSize) { this.text = text; this.x = x; this.y = y; this.align = align; this.fixedSize = fixedSize; // some texts should not be zoomed } } protected float zoom; // We need a seperate program behaviour for 10% and 20% zoom. Otherwise manual resized entities would have the following bugs: // 10%: entity grow without end, 20%: relations don't stick on the right or bottom end of entity private boolean bugfix; protected Graphics2D g2; protected float temp; protected int width, height; protected Composite[] composites; private String code; private final Vector shapes = new Vector(); private final Vector texts = new Vector(); // The temp-variables are needed to store styles with setLineType etc. methods temporarily so that draw-Methods know the actual set style private LineType tmpLineType; private int tmpLineThickness; private Color tmpFgColor; private Color tmpBgColor; private float tmpAlpha; private boolean specialLine, specialFgColor, specialBgColor; private boolean wordWrap = false; private boolean allowResize = true; public abstract void paint(); public final void setCode(String code) { this.code = code; } public final String getCode() { return code; } private void drawShapes() { g2.setColor(bgColor); g2.setComposite(composites[1]); for (StyleShape s : shapes) { specialBgColor = !s.getBgColor().equals(bgColor); if (specialBgColor) { g2.setColor(s.getBgColor()); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, s.getAlpha())); } g2.fill(s.getShape()); if (specialBgColor) { g2.setColor(bgColor); g2.setComposite(composites[1]); } } g2.setComposite(composites[0]); g2.setColor(fgColor); for (StyleShape s : shapes) { specialLine = s.getLineType() != LineType.SOLID || s.getLineThickness() != FacetConstants.LINE_WIDTH_DEFAULT; specialFgColor = !s.getFgColor().equals(Converter.convert(ColorOwn.DEFAULT_FOREGROUND)); if (specialLine) { g2.setStroke(Utils.getStroke(s.getLineType(), s.getLineThickness())); } if (specialFgColor) { if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(Converter.convert(ColorOwn.SELECTION_FG)); } else { g2.setColor(s.getFgColor()); } } g2.draw(s.getShape()); if (specialLine) { g2.setStroke(Utils.getStroke(LineType.SOLID, (float) FacetConstants.LINE_WIDTH_DEFAULT)); } if (specialFgColor) { g2.setColor(fgColor); } } for (Text t : texts) { boolean applyZoom = true; if (t.fixedSize != null) { Main.getHandlerForElement(this).getFontHandler().setFontSize((double) t.fixedSize); applyZoom = false; } Main.getHandlerForElement(this).getFontHandler().writeText(g2, t.text, t.x, t.y, t.align, applyZoom); if (t.fixedSize != null) { Main.getHandlerForElement(this).getFontHandler().resetFontSize(); } } texts.clear(); shapes.clear(); } @Override public final void paintEntity(Graphics g) { g2 = (Graphics2D) g; composites = colorize(g2); g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(fgColor); zoom = Main.getHandlerForElement(this).getZoomFactor(); if (zoom < 0.25) { bugfix = true; } else { bugfix = false; } // width and height must be zoomed back to 100% before any custom code is applied temp = getRectangle().width; width = Math.round(temp / zoom); // use Math.round cause (int) would round down from 239.99998 to 240 temp = getRectangle().height; height = Math.round(temp / zoom); // Set width and height on grid (used for manually resized custom elements mainly width = onGrid(width); height = onGrid(height); // secure this thread before executing the code! // String key = "R" + Math.random(); // CustomElementSecurityManager.addThread(Thread.currentThread(), key); resetAll(); // Reset all tempstyle variables before painting paint(); // calls the paint method of the specific custom element // CustomElementSecurityManager.remThread(Thread.currentThread(), key); width = onGrid(width); height = onGrid(height); // After the custom code we zoom the width and height back width *= zoom; height *= zoom; drawShapes(); // Resize elements if manual resize is not set // if (!this.allowResize || (this.autoResizeandManualResizeEnabled() && !this.isManualResized())) { // CHANGED: Resize every custom object by +1px to get consistent height and width if (!bugfix) { this.setSize(width + 1, height + 1); // } } } @Override public GridElement cloneFromMe() { CustomElement e = (CustomElement) super.cloneFromMe(); e.code = code; return e; } @CustomFunction(param_defaults = "text,x,y") protected final int print(String text, int x, int inY) { int y = inY; List list = wordWrap ? splitString(text, width, Main.getHandlerForElement(this)) : Arrays.asList(new String[] { text }); for (String s : list) { texts.add(new Text(s, (int) (x * zoom), (int) (y * zoom), AlignHorizontal.LEFT)); y += textHeight(); } return y - inY; } @CustomFunction(param_defaults = "text,y") protected final int printLeft(String text, int inY) { int y = inY; List list = wordWrap ? splitString(text, width, Main.getHandlerForElement(this)) : Arrays.asList(new String[] { text }); for (String s : list) { texts.add(new Text(s, (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), (int) (y * zoom), AlignHorizontal.LEFT)); y += textHeight(); } return y - inY; } @CustomFunction(param_defaults = "text,y") protected final int printRight(String text, int inY) { int y = inY; List list = wordWrap ? splitString(text, width, Main.getHandlerForElement(this)) : Arrays.asList(new String[] { text }); for (String s : list) { texts.add(new Text(s, (int) (width * zoom - textWidth(s, true)), (int) (y * zoom), AlignHorizontal.LEFT)); y += textHeight(); } return y - inY; } @CustomFunction(param_defaults = "text,y") protected final int printCenter(String text, int inY) { int y = inY; List list = wordWrap ? splitString(text, width, Main.getHandlerForElement(this)) : Arrays.asList(new String[] { text }); for (String s : list) { texts.add(new Text(s, (int) ((onGrid(width) * zoom - textWidth(s, true)) / 2), (int) (y * zoom), AlignHorizontal.LEFT)); y += textHeight(); } return y - inY; } @CustomFunction(param_defaults = "text,x,y,fixedFontSize") protected final int printFixedSize(String text, int x, int inY, int fixedFontSize) { int y = inY; List list = wordWrap ? splitString(text, width, Main.getHandlerForElement(this)) : Arrays.asList(new String[] { text }); for (String s : list) { texts.add(new Text(s, x, y, AlignHorizontal.LEFT, fixedFontSize)); y += textHeight(); } return y - inY; } @CustomFunction(param_defaults = "value") protected final int onGrid(double value) { return onGrid(value, false); } @CustomFunction(param_defaults = "value, roundUp") protected final int onGrid(double value, boolean roundUp) { if (value % 10 != 0) { value -= value % 10; if (roundUp) { value += 10; } } // BUGFIX for 10% and 20% zoom: Otherwise a manual resized entity border wouldn't be visible because of the exclusion of line 146 if (bugfix) { value--; } return (int) value; } @CustomFunction(param_defaults = "value1,value2") protected final int min(int value1, int value2) { return Math.min(value1, value2); } @CustomFunction(param_defaults = "value1,value2") protected final int max(int value1, int value2) { return Math.max(value1, value2); } @CustomFunction(param_defaults = "minWidth, minHeight, horizontalSpacing") protected final void setAutoresize(int minWidth, int minHeight, int horizontalSpacing) { if (!isManualResized()) { height = minHeight; // minimal height width = minWidth; // minimal width // calculates the width and height of the component for (String textline : Utils.decomposeStrings(getPanelAttributes())) { height = height + textHeight(); width = Math.max(textWidth(textline, false) + 10 + horizontalSpacing, width); } if (height < minHeight) { height = minHeight; } if (width < minWidth) { width = minWidth; } } } @Override @CustomFunction(param_defaults = "") public final boolean isManualResized() { return super.isManualResized(); } @CustomFunction(param_defaults = "wordWrap") public final void setWordWrap(boolean wordWrap) { this.wordWrap = wordWrap; } @CustomFunction(param_defaults = "") public final boolean isWordWrap() { return wordWrap; } @CustomFunction(param_defaults = "x, y, width, height, start, extent") protected final void drawArcOpen(float x, float y, float width, float height, float start, float extent) { shapes.add(new StyleShape(new Arc2D.Float(x * zoom, y * zoom, width * zoom, height * zoom, start, extent, Arc2D.OPEN), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, width, height, start, extent") protected final void drawArcChord(float x, float y, float width, float height, float start, float extent) { shapes.add(new StyleShape(new Arc2D.Float(x * zoom, y * zoom, width * zoom, height * zoom, start, extent, Arc2D.CHORD), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, width, height, start, extent") protected final void drawArcPie(float x, float y, float width, float height, float start, float extent) { shapes.add(new StyleShape(new Arc2D.Float(x * zoom, y * zoom, width * zoom, height * zoom, start, extent, Arc2D.PIE), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, radius") protected final void drawCircle(int x, int y, int radius) { shapes.add(new StyleShape(new Ellipse2D.Float((int) ((x - radius) * zoom), (int) ((y - radius) * zoom), (int) (radius * 2 * zoom), (int) (radius * 2 * zoom)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2") protected final void drawCurveCubic(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2) { shapes.add(new StyleShape(new CubicCurve2D.Float(x1 * zoom, y1 * zoom, ctrlx1 * zoom, ctrly1 * zoom, ctrlx2 * zoom, ctrly2 * zoom, x2 * zoom, y2 * zoom), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x1, y1, ctrlx, ctrly, x2, y2") protected final void drawCurveQuad(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) { shapes.add(new StyleShape(new QuadCurve2D.Float(x1 * zoom, y1 * zoom, ctrlx * zoom, ctrly * zoom, x2 * zoom, y2 * zoom), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, radiusX, radiusYs") protected final void drawEllipse(int x, int y, int radiusX, int radiusY) { shapes.add(new StyleShape(new Ellipse2D.Float((int) ((x - radiusX) * zoom), (int) ((y - radiusY) * zoom), (int) (radiusX * 2 * zoom), (int) (radiusY * 2 * zoom)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x1, y1, x2, y2") protected final void drawLine(int x1, int y1, int x2, int y2) { shapes.add(new StyleShape(new Line2D.Float((int) (x1 * zoom), (int) (y1 * zoom), (int) (x2 * zoom), (int) (y2 * zoom)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "y") protected final void drawLineHorizontal(int y) { shapes.add(new StyleShape(new Line2D.Float((int) (0 * zoom), (int) (y * zoom), Main.getHandlerForElement(this).realignToGrid(false, (int) (width * zoom), true), (int) (y * zoom)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x") protected final void drawLineVertical(int x) { shapes.add(new StyleShape(new Line2D.Float((int) (x * zoom), (int) (0 * zoom), (int) (x * zoom), Main.getHandlerForElement(this).realignToGrid(false, (int) (height * zoom), true)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "polygon") protected final void drawPolygon(Polygon polygon) { for (int i = 0; i < polygon.xpoints.length; i++) { polygon.xpoints[i] *= zoom; } for (int i = 0; i < polygon.ypoints.length; i++) { polygon.ypoints[i] *= zoom; } shapes.add(new StyleShape(polygon, tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, width, height") protected final void drawRectangle(int x, int y, int width, int height) { shapes.add(new StyleShape(new Rectangle((int) (x * zoom), (int) (y * zoom), (int) (width * zoom), (int) (height * zoom)), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } @CustomFunction(param_defaults = "x, y, width, height, arcw, arch") protected final void drawRectangleRound(int x, int y, int width, int height, float arcw, float arch) { shapes.add(new StyleShape(new RoundRectangle2D.Float((int) (x * zoom), (int) (y * zoom), (int) (width * zoom), (int) (height * zoom), arcw * zoom, arch * zoom), tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } // EXAMPLE: drawShape(new java.awt.geom.RoundRectangle2D.Float(10,10, 50, 40, 15,15)); // WARNING: Shapes aren't zoomed automatically @CustomFunction(param_defaults = "shape") protected final void drawShape(Shape shape) { shapes.add(new StyleShape(shape, tmpLineType, tmpLineThickness, tmpFgColor, tmpBgColor, tmpAlpha)); } /* STYLING METHODS */ @CustomFunction(param_defaults = "lineType") protected final void setLineType(int lineType) { if (lineType == 0) { tmpLineType = LineType.SOLID; } else if (lineType == 1) { tmpLineType = LineType.DASHED; } else if (lineType == 2) { tmpLineType = LineType.DOTTED; } else if (lineType == 3) { tmpLineType = LineType.DOUBLE; } else if (lineType == 4) { tmpLineType = LineType.DOUBLE_DASHED; } else if (lineType == 5) { tmpLineType = LineType.DOUBLE_DOTTED; } else { tmpLineType = LineType.SOLID; } } @CustomFunction(param_defaults = "lineThickness") protected final void setLineThickness(int lineThickness) { tmpLineThickness = lineThickness; } @CustomFunction(param_defaults = "foregroundColor") protected final void setForegroundColor(String fgColorString) { tmpFgColor = Converter.convert(ColorOwn.forStringOrNull(fgColorString, Transparency.FOREGROUND)); if (tmpFgColor == null) { tmpFgColor = fgColor; // unknown colors resolve to default color } } @CustomFunction(param_defaults = "backgroundColor") protected final void setBackgroundColor(String bgColorString) { // OldGridElements apply transparency for background explicitly, therefore don't apply it here tmpBgColor = Converter.convert(ColorOwn.forStringOrNull(bgColorString, Transparency.FOREGROUND)); if (tmpBgColor == null) { tmpBgColor = bgColor; // unknown colors resolve to default color } // Transparency is 0% if none or 50% if anything else if (bgColorString.equals("none")) { tmpAlpha = OldGridElement.ALPHA_FULL_TRANSPARENCY; } else { tmpAlpha = OldGridElement.ALPHA_MIDDLE_TRANSPARENCY; } } @CustomFunction(param_defaults = "") protected final void resetAll() { tmpLineThickness = (int) FacetConstants.LINE_WIDTH_DEFAULT; tmpLineType = LineType.SOLID; tmpFgColor = fgColor; tmpBgColor = bgColor; tmpAlpha = alphaFactor; } protected final int textHeight() { return (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize(false) + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(false)); } protected final int textWidth(String text, boolean applyZoom) { return (int) (Main.getHandlerForElement(this).getFontHandler().getTextSize(text, applyZoom).getWidth() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(applyZoom)); } protected final int textWidth(String text) { return textWidth(text, false); } protected final void allowResize(boolean allow) { allowResize = allow; } @Override public Set getResizeArea(int x, int y) { if (allowResize) { return super.getResizeArea(x, y); } else { return new HashSet(); } } private static List splitString(String text, float width, DiagramHandler handler) { StringBuilder stringBuilder = new StringBuilder(text); int lastEmptyChar = -1; // is -1 if there was no ' ' in this line int firstCharInLine = 0; for (int i = 0; i < text.length(); i++) { if (stringBuilder.charAt(i) == ' ') { lastEmptyChar = i; } else if (stringBuilder.charAt(i) == '\n') { lastEmptyChar = -1; firstCharInLine = i + 1; } if (handler.getFontHandler().getTextWidth(text.substring(firstCharInLine, i), false) + 15 > width) { if (lastEmptyChar != -1) { stringBuilder.setCharAt(lastEmptyChar, '\n'); firstCharInLine = lastEmptyChar + 1; lastEmptyChar = -1; } else { stringBuilder.insert(i, '\n'); firstCharInLine = i + 1; } } } return Arrays.asList(stringBuilder.toString().split("\\n")); } @Override public boolean isDeprecated() { return false; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/0000755000175000017500000000000012533641120023612 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/Role.java0000644000175000017500000000155312533641120025362 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class Role extends Rectangle { String _string; public String getString() { return _string; } public Role(String s, int a, int b, int c, int d) { super(a, b, c, d); _string = s; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (_string == null ? 0 : _string.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } Role other = (Role) obj; if (_string == null) { if (other._string != null) { return false; } } else if (!_string.equals(other._string)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/Arrow.java0000644000175000017500000000605212533641120025552 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; public class Arrow extends Rectangle { private Point _arrowEndA; private Point _arrowEndB; // A.Mueller start private Point _crossEndA; private Point _crossEndB; private int _arcStart; private int _arcEnd; // A.Mueller end public Point getArrowEndA() { return _arrowEndA; } public Point getArrowEndB() { return _arrowEndB; } public void setArrowEndA(Point p) { _arrowEndA = p; } public void setArrowEndB(Point p) { _arrowEndB = p; } // A.Mueller start public void setCrossEndA(Point p) { _crossEndA = p; } public void setCrossEndB(Point p) { _crossEndB = p; } public int getArcStart() { return _arcStart; } public int getArcEnd() { return _arcEnd; } public void setArcStart(int a) { _arcStart = a; } public void setArcEnd(int a) { _arcEnd = a; } public Point getCrossEndA() { return _crossEndA; } public Point getCrossEndB() { return _crossEndB; } // A.Mueller end private String _arrowType = null; public String getString() { return _arrowType; } public Arrow(String arrowType) { super(0, 0, 1, 1); _arrowType = arrowType; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + _arcEnd; result = prime * result + _arcStart; result = prime * result + (_arrowEndA == null ? 0 : _arrowEndA.hashCode()); result = prime * result + (_arrowEndB == null ? 0 : _arrowEndB.hashCode()); result = prime * result + (_arrowType == null ? 0 : _arrowType.hashCode()); result = prime * result + (_crossEndA == null ? 0 : _crossEndA.hashCode()); result = prime * result + (_crossEndB == null ? 0 : _crossEndB.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } Arrow other = (Arrow) obj; if (_arcEnd != other._arcEnd) { return false; } if (_arcStart != other._arcStart) { return false; } if (_arrowEndA == null) { if (other._arrowEndA != null) { return false; } } else if (!_arrowEndA.equals(other._arrowEndA)) { return false; } if (_arrowEndB == null) { if (other._arrowEndB != null) { return false; } } else if (!_arrowEndB.equals(other._arrowEndB)) { return false; } if (_arrowType == null) { if (other._arrowType != null) { return false; } } else if (!_arrowType.equals(other._arrowType)) { return false; } if (_crossEndA == null) { if (other._crossEndA != null) { return false; } } else if (!_crossEndA.equals(other._crossEndA)) { return false; } if (_crossEndB == null) { if (other._crossEndB != null) { return false; } } else if (!_crossEndB.equals(other._crossEndB)) { return false; } return true; } @Override public String toString() { return "Type: " + _arrowType + " / Coordinates: " + x + "," + y; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/NoShape.java0000644000175000017500000000026512533641120026015 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class NoShape extends Rectangle { public NoShape() { super(0, 0, 1, 1); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/EmptyShape.java0000644000175000017500000000032512533641120026534 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class EmptyShape extends Rectangle { public EmptyShape(int fontsize) { super(0, 0, fontsize, fontsize); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/Multiplicity.java0000644000175000017500000000161312533641120027146 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class Multiplicity extends Rectangle { String _string; public String getString() { return _string; } public Multiplicity(String s, int a, int b, int c, int d) { super(a, b, c, d); _string = s; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (_string == null ? 0 : _string.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } Multiplicity other = (Multiplicity) obj; if (_string == null) { if (other._string != null) { return false; } } else if (!_string.equals(other._string)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/Qualifier.java0000644000175000017500000000157712533641120026410 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class Qualifier extends Rectangle { String _string; public String getString() { return _string; } public Qualifier(String s, int a, int b, int c, int d) { super(a, b, c, d); _string = s; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (_string == null ? 0 : _string.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } Qualifier other = (Qualifier) obj; if (_string == null) { if (other._string != null) { return false; } } else if (!_string.equals(other._string)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/relation/Port.java0000644000175000017500000000164112533641120025403 0ustar benbenpackage com.baselet.element.old.relation; import com.baselet.control.basics.geom.Rectangle; public class Port extends Rectangle { String _string; public String getString() { return _string; } public Port(String s, int a, int b, int c, int d) { super(a, b, c, d); _string = s; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (_string == null ? 0 : _string.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } Port other = (Port) obj; if (_string == null) { if (other._string != null) { return false; } } else if (!_string.equals(other._string)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/0000755000175000017500000000000012533641120023426 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/StateSubDiagram.java0000644000175000017500000000165412533641120027316 0ustar benbenpackage com.baselet.element.old.element; // Some import to have access to more Java features import java.awt.Graphics; import java.awt.Graphics2D; import com.baselet.control.Main; @SuppressWarnings("serial") public class StateSubDiagram extends State { @Override public void paintEntity(Graphics g) { super.paintEntity(g); float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; int w = getRectangle().width; int h = getRectangle().height; // draw substate sign g2.drawRoundRect(w - (int) (65 * zoom), h - (int) (16 * zoom), (int) (20 * zoom), (int) (10 * zoom), (int) (8 * zoom), (int) (8 * zoom)); g2.drawLine(w - (int) (45 * zoom), h - (int) (11 * zoom), w - (int) (35 * zoom), h - (int) (11 * zoom)); g2.drawRoundRect(w - (int) (35 * zoom), h - (int) (16 * zoom), (int) (20 * zoom), (int) (10 * zoom), (int) (8 * zoom), (int) (8 * zoom)); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/AlternativeUseCase.java0000644000175000017500000000446112533641120030025 0ustar benbenpackage com.baselet.element.old.element; // Some import to have access to more Java features import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class AlternativeUseCase extends OldGridElement { // Change this method if you want to edit the graphical // representation of your custom element. @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); boolean center = false; Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (s.equals("--")) { yPos = (int) (35 * zoom); center = true; } else if (center) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - 1) / 2.0, yPos, AlignHorizontal.CENTER); center = false; } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } g2.drawLine(0, (int) (30 * zoom), getRectangle().width - 1, (int) (30 * zoom)); g2.drawOval(getRectangle().width - (int) (59 * zoom), (int) (3 * zoom), (int) (55 * zoom), (int) (20 * zoom)); } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/PackageAggregationHierarchy.javaumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/PackageAggregationHierarchy0000644000175000017500000001250212533641120030713 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class PackageAggregationHierarchy extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); // init graph and colors Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); // extract property strings Vector tmp = Utils.decomposeStrings(getPanelAttributes()); // draw bounding box g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); // init coordinates; int level = 0; double yPos = 10 * zoom; double xPos = 10 * zoom; double packageHeight = Main.getHandlerForElement(this).getFontHandler().getFontSize(); double packageWidth = 2 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); Vector dock = new Vector(); Point nextDock = new Point((int) (xPos + packageWidth / 3 + 0.5), (int) (2 * packageHeight + yPos + 0.5)); dock.add(nextDock); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); int currentLineLevel = calculateLevel(s); s = s.replaceAll("\t", ""); // increase level if (currentLineLevel > level && i > 0) { level++; nextDock = new Point((int) (xPos + packageWidth / 3 + 0.5), (int) (2 * packageHeight + yPos + 0.5)); dock.add(nextDock); nextDock = dock.elementAt(level - 1); drawDockAnchor(g2, nextDock); } // decrease level if (currentLineLevel < level) { level = currentLineLevel; } xPos = 10 * zoom + (float) (packageWidth * level * 1.5); drawPackage(g2, xPos, yPos, packageHeight, packageWidth, s); // draw docks for non root elements if (level > 0) { // change dock color to red if too much tabs occur Color color = g2.getColor(); if (currentLineLevel > level) { g2.setColor(Color.red); } nextDock = dock.elementAt(level - 1); drawDock(g2, nextDock, xPos, yPos, packageHeight); // reset color g2.setColor(color); } nextDock = new Point((int) (xPos + packageWidth / 3 + 0.5), (int) (2 * packageHeight + yPos + 0.5)); dock.set(level, nextDock); yPos += 2 * packageHeight + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } @Override public StickingPolygon generateStickingBorder() { StickingPolygon p = new StickingPolygon(0, 0); return p; } private void drawDockAnchor(Graphics2D g2, Point nextDock) { // Logger.getAnonymousLogger().info("\ndrawDock: \ndock.x/y: " + nextDock.x + "/" + nextDock.y); float zoom = Main.getHandlerForElement(this).getZoomFactor(); g2.drawOval(nextDock.x - (int) (5 * zoom + 0.5), nextDock.y - (int) (10 * zoom + 0.5), (int) (10 * zoom + 0.5), (int) (10 * zoom + 0.5)); g2.drawLine(nextDock.x, nextDock.y - (int) (8 * zoom + 0.5), nextDock.x, nextDock.y - (int) (2 * zoom + 0.5)); g2.drawLine(nextDock.x - (int) (3 * zoom + 0.5), nextDock.y - (int) (5 * zoom + 0.5), nextDock.x + (int) (3 * zoom + 0.5), nextDock.y - (int) (5 * zoom + 0.5)); } private void drawDock(Graphics2D g2, Point nextDock, double xPos, double yPos, double packageHeight) { // Logger.getAnonymousLogger().info("\ndrawDock: \ndock.x/y: " + nextDock.x + "/" + nextDock.y + "\nx/yPos: " + xPos + "/" + yPos); g2.drawLine(nextDock.x, nextDock.y, nextDock.x, (int) (packageHeight / 2 + 0.5) + (int) (yPos + 0.5)); g2.drawLine(nextDock.x, (int) (packageHeight / 2 + 0.5) + (int) (yPos + 0.5), (int) (xPos + 0.5), (int) (packageHeight / 2 + 0.5) + (int) (yPos + 0.5)); } private void drawPackage(Graphics2D g2, double xPos, double yPos, double packageHeight, double packageWidth, String name) { // Logger.getAnonymousLogger().info("\nxPos: " + xPos + "\nyPos: " + yPos + "\nzoom: " + zoom + "\nname: " + name); g2.drawRect((int) (xPos + 0.5), (int) (yPos + 0.5), (int) (packageWidth / 3 + 0.5), (int) (packageHeight / 4 + 0.5)); g2.drawRect((int) (xPos + 0.5), (int) (packageHeight / 4 + 0.5) + (int) (yPos + 0.5), (int) (packageWidth + 0.5), (int) (packageHeight + 0.5)); Main.getHandlerForElement(this).getFontHandler().writeText(g2, name, (int) (xPos + packageWidth + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + 0.5), (int) (packageHeight + yPos + 0.5), AlignHorizontal.LEFT); } // calculates the hierarchy level according to tab count in the string protected int calculateLevel(String s) { int level = 0; while (s.length() > 0 && s.charAt(0) == '\t') { level++; s = s.substring(1); } // Logger.getAnonymousLogger().info("string=="+s+";index=="+level); return level; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/InitialState.java0000644000175000017500000000142412533641120026664 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class InitialState extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); g2.fillOval(0, 0, getRectangle().width, getRectangle().height); } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Artefact.java0000644000175000017500000000526612533641120026033 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Artefact extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); // symbol outline g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) (10 * zoom); int startY = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), startY + yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // small component symbol g2.drawLine(getRectangle().width - (int) (30 * zoom), (int) (10 * zoom), getRectangle().width - (int) (30 * zoom), (int) (40 * zoom)); g2.drawLine(getRectangle().width - (int) (30 * zoom), (int) (40 * zoom), getRectangle().width - (int) (5 * zoom), (int) (40 * zoom)); g2.drawLine(getRectangle().width - (int) (5 * zoom), (int) (40 * zoom), getRectangle().width - (int) (5 * zoom), (int) (20 * zoom)); g2.drawLine(getRectangle().width - (int) (5 * zoom), (int) (20 * zoom), getRectangle().width - (int) (15 * zoom), (int) (10 * zoom)); g2.drawLine(getRectangle().width - (int) (15 * zoom), (int) (10 * zoom), getRectangle().width - (int) (30 * zoom), (int) (10 * zoom)); g2.drawLine(getRectangle().width - (int) (5 * zoom), (int) (20 * zoom), getRectangle().width - (int) (15 * zoom), (int) (20 * zoom)); g2.drawLine(getRectangle().width - (int) (15 * zoom), (int) (20 * zoom), getRectangle().width - (int) (15 * zoom), (int) (10 * zoom)); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Database.java0000644000175000017500000000541312533641120026000 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Database extends OldGridElement { // Change this method if you want to edit the graphical // representation of your custom element. @Override public void paintEntity(Graphics g) { // Some unimportant initialization stuff; setting color, font // quality, etc. You should not have to change this. Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); int inset = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); // It's getting interesting here: // First, the strings you type in the element editor are read and // split into lines. // Then, by default, they are printed out on the element, aligned // to the left. // Change this to modify this default text printing and to react // to special strings // (like the "--" string in the UML class elements which draw a line). Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = inset + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); boolean CENTER = true; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { CENTER = false; g2.drawLine(0, yPos, getRectangle().width, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } // Finally, change other graphical attributes using // drawLine, getWidth, getHeight.. g2.drawLine(0, getRectangle().height - 1 - inset / 2, 0, inset / 2); g2.drawOval(0, 0, getRectangle().width, inset); g2.drawArc(0, getRectangle().height - 1 - inset, getRectangle().width, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 180, 180); g2.drawLine(getRectangle().width - 1, inset / 2, getRectangle().width - 1, getRectangle().height - 1 - inset / 2); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Relation.java0000644000175000017500000020701012533641120026046 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.util.Collections; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.Constants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.Selector; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.OldGridElement; import com.baselet.element.old.relation.Arrow; import com.baselet.element.old.relation.EmptyShape; import com.baselet.element.old.relation.Multiplicity; import com.baselet.element.old.relation.NoShape; import com.baselet.element.old.relation.Port; import com.baselet.element.old.relation.Qualifier; import com.baselet.element.old.relation.Role; import com.baselet.element.sticking.StickingPolygon; import com.baselet.element.sticking.polygon.NoStickingPolygonGenerator; @SuppressWarnings("serial") public class Relation extends OldGridElement { String beginQualifier; String endQualifier; String beginArrow; String endArrow; String beginMultiplicity; String endMultiplicity; String beginRole; String endRole; String lineType; String eerRelDir; Vector _strings; // A.Mueller start String clientServer; // A.Mueller end // G.Mueller start String beginPort; String endPort; String middleArrow; String csdStartText; // Arrow-Text for composite structure diagram String csdEndText; // G.Mueller end private final float SELECTBOXSIZE = 12; private final float SELECTCIRCLESIZE = 15; private Vector getStrings() { if (_strings == null) { _strings = new Vector(); } return _strings; } private void setStrings(Vector v) { _strings = v; } private Point getCenterOfLine() { Point ret = new Point(); if (getLinePoints().size() % 2 == 1) { ret = getLinePoints().elementAt(getLinePoints().size() / 2); } else { Point p1 = getLinePoints().elementAt(getLinePoints().size() / 2); Point p2 = getLinePoints().elementAt(getLinePoints().size() / 2 - 1); ret.x = (p1.x + p2.x) / 2; ret.y = (p1.y + p2.y) / 2; } return ret; } @Override public String getAdditionalAttributes() { Vector tmp = new Vector(); // tmp.add(beginQualifier); // tmp.add(endQualifier); // tmp.add(beginArrow); // tmp.add(endArrow); // tmp.add(beginMultiplicity); // tmp.add(endMultiplicity); // tmp.add(beginRole); // tmp.add(endRole); // tmp.add(lineType); /* tmp.add(""+this.getX()); tmp.add(""+this.getY()); tmp.add(""+this.getWidth()); tmp.add(""+this.getHeight()); */ for (int i = 0; i < getLinePoints().size(); i++) { Point p = getLinePoints().elementAt(i); String s1 = "" + p.x; String s2 = "" + p.y; tmp.add(s1); tmp.add(s2); } String ret = Utils.composeStrings(tmp, Constants.DELIMITER_ADDITIONAL_ATTRIBUTES); return ret; } @Override public void setAdditionalAttributes(String s) { getLinePoints().clear(); Vector tmp = Utils.decomposeStringsIncludingEmptyStrings(s, Constants.DELIMITER_ADDITIONAL_ATTRIBUTES); for (int i = 0; i < tmp.size(); i = i + 2) { int x = Integer.parseInt(tmp.elementAt(i)); int y = Integer.parseInt(tmp.elementAt(i + 1)); getLinePoints().add(new Point(x, y)); } } @Override public void setPanelAttributes(String state) { beginQualifier = ""; endQualifier = ""; beginArrow = ""; endArrow = ""; beginMultiplicity = ""; endMultiplicity = ""; beginRole = ""; endRole = ""; lineType = "-"; eerRelDir = ""; // G.Mueller.Start middleArrow = ""; beginPort = ""; endPort = ""; // G.Mueller. End setStrings(null); super.setPanelAttributes(state); Vector tmp = Utils.decomposeStrings(state); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.startsWith("q1=") & s.length() > 3) { beginQualifier = s.substring(3, s.length()); } else if (s.startsWith("q2=") & s.length() > 3) { endQualifier = s.substring(3, s.length()); } else if (s.startsWith("m1=") & s.length() > 3) { beginMultiplicity = s.substring(3, s.length()); } else if (s.startsWith("m2=") & s.length() > 3) { endMultiplicity = s.substring(3, s.length()); } else if (s.startsWith("r1=") & s.length() > 3) { beginRole = s.substring(3, s.length()); } else if (s.startsWith("r2=") & s.length() > 3) { endRole = s.substring(3, s.length()); } else if (s.startsWith("p1=") & s.length() > 3) { beginPort = s.substring(3, s.length()); } else if (s.startsWith("p2=") & s.length() > 3) { endPort = s.substring(3, s.length()); } else if (s.startsWith("lt=") & s.length() > 3) { csdStartText = ""; csdEndText = ""; // *** if (s.indexOf("<[") >= 0) { beginArrow = "compStart"; if (s.length() > 6) { csdStartText = getCSDText(s)[0]; s = s.replace("<[" + csdStartText + "]", "<[]"); } } if (s.indexOf("]>") >= 0) { endArrow = "compEnd"; if (s.length() > 6) { csdEndText = getCSDText(s)[1]; s = s.replace("[" + csdEndText + "]>", "[]>"); } } if (s.indexOf("]<") >= 0) { beginArrow = beginArrow + "del"; } if (s.indexOf(">[") >= 0) { endArrow = endArrow + "del"; } if (s.indexOf(">>>>>") >= 0) { endArrow = "<<<"; } else if (s.indexOf(">>>>") >= 0) { endArrow = "X"; } else if (s.indexOf(">>>") >= 0) { endArrow = "x"; } else if (s.indexOf(">>") >= 0) { endArrow = "<<"; } else if (s.indexOf("m>") >= 0) { endArrow = "crowsFoot"; } else if (s.indexOf(">") >= 0) { if (endArrow.equals("")) { endArrow = "<"; } } if (s.indexOf("<<<<<") >= 0) { beginArrow = "<<<"; } else if (s.indexOf("<<<<") >= 0) { beginArrow = "X"; } else if (s.indexOf("<<<") >= 0) { beginArrow = "x"; } else if (s.indexOf("<<") >= 0) { beginArrow = "<<"; } else if (s.indexOf("= 0) { beginArrow = "crowsFoot"; } else if (s.indexOf("<") >= 0) { if (beginArrow.equals("")) { beginArrow = "<"; } } if (s.indexOf("") >= 0) { beginArrow = ""; endArrow = ""; eerRelDir = "EER1"; } else if (s.indexOf("= 0) { beginArrow = ""; endArrow = ""; eerRelDir = "EER2"; } else if (s.indexOf("EER>") >= 0) { beginArrow = ""; endArrow = ""; eerRelDir = "EER3"; } else if (s.indexOf("EER") >= 0) { beginArrow = ""; endArrow = ""; eerRelDir = "EER_SUBCLASS"; } // A.Mueller Beginn clientServer = ""; // *** if (s.indexOf("(()") >= 0) { // beginArrow = ""; G.Mueller clientServer = "provideRequire"; } else if (s.indexOf("())") >= 0) { // endArrow = ""; G.Mueller clientServer = "requireProvide"; } if (s.indexOf("<(+)") >= 0) { beginArrow = "packageStart"; clientServer = " "; } else if (s.indexOf("<()") >= 0) { clientServer = "start"; // used for setting the startpoint // nonstickable beginArrow = "require"; } else if (s.indexOf("<(") >= 0) { clientServer = "start"; // used for setting the // startpoint // not stickable beginArrow = "provide"; } else if (s.indexOf("= 0) { beginArrow = "n"; } if (s.indexOf("(+)>") >= 0) { endArrow = "packageEnd"; clientServer = " "; } else if (s.indexOf("()>") >= 0) { clientServer = "end"; // used for setting the endpoint // nonstickable endArrow = "require"; } else if (s.indexOf(")>") >= 0) { clientServer = "end"; // used for setting the endpoint // nonstickable endArrow = "provide"; } else if (s.indexOf("x>") >= 0) { endArrow = "n"; } // A.Mueller End // Mueller G. End // Mueller G. Start if (s.indexOf(">()") >= 0 && clientServer.equals("")) { middleArrow = "delegationArrowRight"; if (endArrow.equals("<")) { endArrow = ""; } } else if (s.indexOf("()<") >= 0 && clientServer.equals("")) { middleArrow = "delegationArrowLeft"; if (beginArrow.equals("<")) { beginArrow = ""; } } else if (s.indexOf("()") >= 0 && clientServer.equals("")) { middleArrow = "delegation"; } else if (s.indexOf("(") >= 0 && clientServer.equals("")) { middleArrow = "delegationStart"; lineType = "-."; } else if (s.indexOf(")") >= 0 && clientServer.equals("")) { middleArrow = "delegationEnd"; lineType = ".-"; } // G.Mueller: LineTyp check here: if (s.indexOf(".") >= 0 & s.indexOf("-") >= s.indexOf(".")) { lineType = ".-"; } else if (s.indexOf("-") >= 0 & s.indexOf(".") >= s.indexOf("-")) { lineType = "-."; } else if (s.indexOf(LineType.DOTTED.getValue()) >= 0) { lineType = LineType.DOTTED.getValue(); } else if (s.indexOf(LineType.DASHED.getValue()) >= 0) { lineType = LineType.DASHED.getValue(); } else if (s.indexOf(LineType.SOLID.getValue()) >= 0) { lineType = LineType.SOLID.getValue(); } else if (s.substring(3, s.length()).indexOf(LineType.DOUBLE.getValue()) >= 0) { lineType = LineType.DOUBLE.getValue(); } else if (s.indexOf(LineType.DOUBLE_DOTTED.getValue()) >= 0) { lineType = LineType.DOUBLE_DOTTED.getValue(); } else if (s.indexOf(LineType.DOUBLE_DASHED.getValue()) >= 0) { lineType = LineType.DOUBLE_DASHED.getValue(); } } else { getStrings().add(s); } } } // Created objects have no sideeffects // Only exception: no point is outside shape // At least 2 points must be provided public static Vector getIntersectingLineSegment(Area r, Vector points) { Vector ret = new Vector(); // If no segment found, take last two points Point pp_end = points.elementAt(points.size() - 1); Point pp_start = points.elementAt(points.size() - 2); for (int i = 1; i < points.size(); i++) { pp_end = points.elementAt(i); if (!r.contains(Converter.convert(pp_end))) { // End point of intersecting line found pp_start = points.elementAt(i - 1); ret.add(pp_start); ret.add(pp_end); return ret; } } ret.add(pp_start); ret.add(pp_end); return ret; } public static Point moveNextTo(Area rFixed, Rectangle rMovable, Point pStart, Point pEnd) { // These ints can simply be added to line int centerDiffX = -rMovable.getWidth() / 2; int centerDiffY = -rMovable.getHeight() / 2; int vectorX = pEnd.x - pStart.x; int vectorY = pEnd.y - pStart.y; int startx = pStart.x; int starty = pStart.y; int endx = pEnd.x; int endy = pEnd.y; for (@SuppressWarnings("unused") int i = 0;; i++) { endx += vectorX; endy += vectorY; rMovable.setLocation(endx + centerDiffX, endy + centerDiffY); if (!rFixed.intersects(Converter.convert(rMovable))) { break; } } int newx = 0; int newy = 0; for (int i = 0; i < 10; i++) { newx = (endx + startx) / 2; newy = (endy + starty) / 2; rMovable.setLocation(newx + centerDiffX, newy + centerDiffY); if (rFixed.intersects(Converter.convert(rMovable))) { startx = newx; starty = newy; } else { endx = newx; endy = newy; } } Point ret = new Point(newx + centerDiffX, newy + centerDiffY); return ret; } public boolean lineUp(Vector shapes, Vector points, int hotspotx, int hotspoty) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); // Remove point with the same coordinates for (int i = points.size() - 1; i > 0; i--) { Point p1 = points.elementAt(i); Point p2 = points.elementAt(i - 1); if (p1.x == p2.x & p1.y == p2.y) { points.removeElementAt(i); } } if (points.size() <= 1) { return false; } if (shapes.size() <= 1) { return true; } // Vector ret=new Vector(); // Rectangle rFixed; Rectangle rMovable; Area tmpArea = new Area(); for (int i = 0; i < shapes.size() - 1; i++) { Rectangle r = shapes.elementAt(i); if (i == 0) { // The hotspot of the first element is set Point p = points.elementAt(0); r.setLocation(p.x - hotspotx, p.y - hotspoty); } Area a = new Area(Converter.convert(r)); tmpArea.add(a); // rFixed=(Rectangle)shapes.elementAt(i); rMovable = shapes.elementAt(i + 1); /* if (i==0) { // The hotspot of the first element is set Point p=(Point)points.elementAt(0); rFixed.setLocation(p.x-hotspotx,p.y-hotspoty); } */ Vector tmp = getIntersectingLineSegment(tmpArea, points); Point startIntersectingLine = tmp.elementAt(0); Point endIntersectingLine = tmp.elementAt(1); Point res = moveNextTo(tmpArea, rMovable, startIntersectingLine, endIntersectingLine); // ret.add(res); if (rMovable instanceof Arrow) { Arrow arrow = (Arrow) rMovable; Point diffA = new Point(-startIntersectingLine.x + endIntersectingLine.x, -startIntersectingLine.y + endIntersectingLine.y); Point diffB1 = new Point(diffA.y, -diffA.x); Point diffB2 = new Point(-diffB1.x, -diffB1.y); Point a1 = new Point(2 * diffA.x + diffB1.x, 2 * diffA.y + diffB1.y); Point a2 = new Point(2 * diffA.x + diffB2.x, 2 * diffA.y + diffB2.y); a1 = Utils.normalize(a1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); a2 = Utils.normalize(a2, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); arrow.setArrowEndA(a1); arrow.setArrowEndB(a2); // A.Mueller start if (arrow.getString().equals("n")) { // this is pretty much the same as above, but it // was hard to work out what it does so here it // is repeated with better names and some // comments. I only made the original vector longer and // increased the pixelsize(fontsize) // to get the point further towards the center. Point start = startIntersectingLine; Point end = endIntersectingLine; // vectorA is the vector between the two points which is the // line between the points... Point vectorA = new Point(-start.x + end.x, -start.y + end.y); // vector down is a vector standing 90 degrees on the line, // vector up is the same in the opposite direction.. Point vectorDown = new Point(vectorA.y, -vectorA.x); Point vectorUp = new Point(-vectorDown.x, -vectorDown.y); Point newA1 = new Point(4 * vectorA.x + vectorDown.x, 4 * vectorA.y + vectorDown.y); Point newA2 = new Point(4 * vectorA.x + vectorUp.x, 4 * vectorA.y + diffB2.y); // this calculates the proportion of the two dimensions of // the point compared to each other // (which means propX + propY = 1) and multiplies it with // the second parameter... newA1 = Utils.normalize(newA1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2); newA2 = Utils.normalize(newA2, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2); arrow.setCrossEndA(newA1); arrow.setCrossEndB(newA2); } else if (arrow.getString().equals("require")) { int size = (int) (20 * zoom); Point start = startIntersectingLine; Point end = endIntersectingLine; Point upperLeft = new Point(); Point bottomDown = new Point(); if (start.getX() > end.getX()) { upperLeft = new Point(0, -size / 2); bottomDown = new Point(size, size / 2); } else if (start.getX() < end.getX()) { upperLeft = new Point(-size, -size / 2); bottomDown = new Point(0, size / 2); } else if (start.getX() == end.getX()) { if (start.getY() < end.getY()) { upperLeft = new Point(-size / 2, -size); bottomDown = new Point(size / 2, 0); } else if (start.getY() > end.getY()) { upperLeft = new Point(-size / 2, 0); bottomDown = new Point(size / 2, size); } } arrow.setCrossEndA(upperLeft); arrow.setCrossEndB(bottomDown); } else if (arrow.getString().equals("provide")) { int size = (int) (30 * zoom); Point start = startIntersectingLine; Point end = endIntersectingLine; Point upperLeft = new Point(); Point bottomDown = new Point(); if (start.getX() > end.getX()) { upperLeft = new Point(0, -size / 2); bottomDown = new Point(size, size / 2); arrow.setArcStart(90); arrow.setArcEnd(180); } else if (start.getX() < end.getX()) { upperLeft = new Point(-size, -size / 2); bottomDown = new Point(0, size / 2); arrow.setArcStart(90); arrow.setArcEnd(-180); } else if (start.getX() == end.getX()) { if (start.getY() < end.getY()) { upperLeft = new Point(-size / 2, -size); bottomDown = new Point(size / 2, 0); arrow.setArcStart(0); arrow.setArcEnd(-180); } else if (start.getY() > end.getY()) { upperLeft = new Point(-size / 2, 0); bottomDown = new Point(size / 2, size); arrow.setArcStart(0); arrow.setArcEnd(180); } } arrow.setCrossEndA(upperLeft); arrow.setCrossEndB(bottomDown); // A.Mueller end } } // ATTENTION: this Recangle will become the rFixed in the next loop rMovable.setLocation(res.x, res.y); } return true; } /** * A relation is only in range (= in the selection frame) if every relation point is in the selection frame */ @Override public boolean isInRange(Rectangle rect1) { // Assume that the rect contains all relation points for (Point p : getLinePoints()) { // We must add the displacement from the top left corner of the drawpanel to the point coordinates Point realPoint = new Point(p.getX() + getRectangle().x, p.getY() + getRectangle().y); // If only one point is not in the selection rectangle, the method returns false if (!rect1.contains(realPoint)) { return false; } } return true; } public boolean isOnLine(int i) { if (i - 1 >= 0 & i + 1 < getLinePoints().size()) { Point x1 = getLinePoints().elementAt(i - 1); Point x2 = getLinePoints().elementAt(i + 1); Point p = getLinePoints().elementAt(i); if (p.distance(x1) + p.distance(x2) < x1.distance(x2) + 5) { return true; } } return false; } public int getWhereToInsert(Point p) { for (int i = 0; i < getLinePoints().size() - 1; i++) { Point x1 = getLinePoints().elementAt(i); Point x2 = getLinePoints().elementAt(i + 1); if (p.distance(x1) + p.distance(x2) < x1.distance(x2) + 5) { return i + 1; } } return -1; } public int getLinePoint(Point p) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); for (int i = 0; i < getLinePoints().size(); i++) { Point x = getLinePoints().elementAt(i); if (p.distance(x) < SELECTCIRCLESIZE * zoom) { return i; } } return -1; } private Vector flipVector(Vector v) { Vector ret = new Vector(); for (int i = v.size() - 1; i >= 0; i--) { ret.add(v.elementAt(i)); } return ret; } @Override public boolean contains(java.awt.Point p) { // other relations which are selected are prioritized for (GridElement other : Main.getHandlerForElement(this).getDrawPanel().getGridElements()) { Selector s = Main.getHandlerForElement(other).getDrawPanel().getSelector(); if (other != this && other instanceof Relation && s.isSelected(other)) { int xDist = getRectangle().x - other.getRectangle().x; int yDist = getRectangle().y - other.getRectangle().y; Point modifiedP = new Point(p.x + xDist, p.y + yDist); // the point must be modified, because the other relation has other coordinates boolean containsHelper = ((Relation) other).calcContains(modifiedP); if (s.isSelected(other) && containsHelper) { return false; } } } return calcContains(Converter.convert(p)); } private boolean calcContains(Point p) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); for (int i = 0; i < getLinePoints().size(); i++) { Point x = getLinePoints().elementAt(i); if (p.distance(x) < SELECTCIRCLESIZE * zoom) { return true; } } for (int i = 0; i < getLinePoints().size() - 1; i++) { Point x1 = getLinePoints().elementAt(i); Point x2 = getLinePoints().elementAt(i + 1); if (p.distance(x1) + p.distance(x2) > x1.distance(x2) + 5) { continue; } // system origin translated to x1 double p1x = x2.getX() - x1.getX(); double p1y = x2.getY() - x1.getY(); double p2x = p.getX() - x1.getX(); double p2y = p.getY() - x1.getY(); // constant - calculated constant by rotating line + calculation intersection point double c = (p1x * p2x + p1y * p2y) / (p1x * p1x + p1y * p1y); // intersection point double i1x = p1x * c; double i1y = p1y * c; // abstand double ax = i1x - p2x; double ay = i1y - p2y; double a = Math.sqrt(ax * ax + ay * ay); if (a < 5) { return true; } } return false; } @Override public boolean contains(int x, int y) { return contains(new java.awt.Point(x, y)); } private Vector _points; public Vector getLinePoints() { if (_points == null) { _points = new Vector(); } return _points; } public void moveLinePoint(int index, int diffx, int diffy) { Point p = getLinePoints().elementAt(index); p.move(diffx, diffy); repaint(); } @Override public GridElement cloneFromMe() { Relation c = new Relation(); c.setPanelAttributes(getPanelAttributes()); c.setAdditionalAttributes(getAdditionalAttributes()); c.setVisible(true); c.setRectangle(getRectangle()); Main.getHandlerForElement(this).setHandlerAndInitListeners(c); return c; } // Polygon to draw the move whole line rectangle + check if it contains the mouse public Polygon getWholeLinePolygon() { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Polygon p = new Polygon(); Point mid; int s = getLinePoints().size(); if (s % 2 == 0 && s > 0) { mid = getCenterOfLine(); } else if (s > 2) { Point p1 = getLinePoints().elementAt(getLinePoints().size() / 2); Point p2 = getLinePoints().elementAt(getLinePoints().size() / 2 + 1); mid = new Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2); } else { return null; } int size = (int) (SELECTBOXSIZE * zoom); size = size / 2; p.addPoint(mid.x - size, mid.y - size); p.addPoint(mid.x + size, mid.y - size); p.addPoint(mid.x + size, mid.y + size); p.addPoint(mid.x - size, mid.y + size); return p; } // checks if the point is contained in the polygon above public boolean isWholeLine(int x, int y) { Polygon p = getWholeLinePolygon(); if (p == null) { return false; } if (p.contains(x, y)) { return true; } return false; } /* (non-Javadoc) * @see main.element.base.Entity#paintEntity(java.awt.Graphics) */ /* (non-Javadoc) * @see main.element.base.Entity#paintEntity(java.awt.Graphics) */ @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); // Just to set anti-aliasing, even if no text // operations occur // g2.setColor(Color.MAGENTA); // g2.drawLine(0,0,0,2); // g2.drawLine(0,0,2,0); // g2.drawLine(this.getWidth()-1-2,this.getHeight()-1, this.getWidth()-1,this.getHeight()-1); // g2.drawLine(this.getWidth()-1,this.getHeight()-1-2, this.getWidth()-1,this.getHeight()-1); // g2.setColor(activeColor); Vector startShapes = new Vector(); Vector endShapes = new Vector(); startShapes.add(new NoShape()); endShapes.add(new NoShape()); if (beginQualifier != null && beginQualifier.length() > 0) { TextLayout tl = new TextLayout(beginQualifier, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Qualifier q = new Qualifier(beginQualifier, 0, 0, (int) tl.getBounds().getWidth() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2, (int) tl.getBounds().getHeight() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2); startShapes.add(q); } if (endQualifier != null && endQualifier.length() > 0) { TextLayout tl = new TextLayout(endQualifier, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Qualifier q = new Qualifier(endQualifier, 0, 0, (int) tl.getBounds().getWidth() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2, (int) tl.getBounds().getHeight() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2); endShapes.add(q); } if (beginArrow != null && beginArrow.length() > 0) { Arrow a = new Arrow(beginArrow); startShapes.add(a); } if (endArrow != null && endArrow.length() > 0) { Arrow a = new Arrow(endArrow); endShapes.add(a); } if (beginMultiplicity != null && beginMultiplicity.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); startShapes.add(e); TextLayout tl = new TextLayout(beginMultiplicity, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Multiplicity m = new Multiplicity(beginMultiplicity, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); startShapes.add(m); } if (endMultiplicity != null && endMultiplicity.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); endShapes.add(e); TextLayout tl = new TextLayout(endMultiplicity, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Multiplicity m = new Multiplicity(endMultiplicity, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); endShapes.add(m); } if (beginRole != null && beginRole.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); startShapes.add(e); // A.Mueller start // calculating the width if we break lines... int position = 0; int lineBreaks = 0; double broadestText = Main.getHandlerForElement(this).getFontHandler().getTextWidth(beginRole); while (position != 1) { int positionNew = beginRole.indexOf("\\\\", position); if (position == 0 && positionNew != -1) { broadestText = 0; } if (positionNew != -1) { broadestText = Math.max(broadestText, Main.getHandlerForElement(this).getFontHandler() .getTextWidth(beginRole.substring(position, positionNew))); if (beginRole.lastIndexOf("\\\\") + 2 != beginRole.length()) { broadestText = Math.max(broadestText, Main.getHandlerForElement(this).getFontHandler().getTextWidth(beginRole.substring(beginRole.lastIndexOf("\\\\") + 2, beginRole.length()))); } lineBreaks++; } position = positionNew + 2; } Role r = new Role(beginRole, 0, 0, (int) broadestText, lineBreaks * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (lineBreaks + 2) * (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); // /* TextLayout tl = new TextLayout(beginRole, this.getHandler().getFont(), Constants.getFRC(g2)); Role r = new Role(beginRole, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); */ // // A.Mueller end startShapes.add(r); } if (endRole != null && endRole.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); endShapes.add(e); // A.Mueller start // calculating the width if we break lines... int position = 0; int lineBreaks = 0; double broadestText = Main.getHandlerForElement(this).getFontHandler().getTextWidth(endRole); while (position != 1) { int positionNew = endRole.indexOf("\\\\", position); if (position == 0 && positionNew != -1) { broadestText = 0; } if (positionNew != -1) { broadestText = Math.max(broadestText, Main.getHandlerForElement(this).getFontHandler().getTextWidth(endRole.substring(position, positionNew))); if (endRole.lastIndexOf("\\\\") + 2 != endRole.length()) { broadestText = Math.max(broadestText, Main.getHandlerForElement(this).getFontHandler().getTextWidth(endRole.substring(endRole.lastIndexOf("\\\\") + 2, endRole.length()))); } lineBreaks++; } position = positionNew + 2; } Role r = new Role(endRole, 0, 0, (int) broadestText, lineBreaks * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (lineBreaks + 2) * (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); // /* TextLayout tl = new TextLayout(endRole, this.getHandler().getFont(), Constants.getFRC(g2)); Role r = new Role(endRole, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); */ // // A.Mueller end endShapes.add(r); } // G.Mueller start if (beginPort != null && beginPort.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); startShapes.add(e); TextLayout tl = new TextLayout(beginPort, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Port p = new Port(beginPort, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); startShapes.add(p); } if (endPort != null && endPort.length() > 0) { EmptyShape e = new EmptyShape((int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); endShapes.add(e); TextLayout tl = new TextLayout(endPort, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Port p = new Port(endPort, 0, 0, (int) tl.getBounds().getWidth(), (int) tl.getBounds().getHeight()); endShapes.add(p); } // G.Mueller end // ****************************************************************** Vector startPoints = new Vector(getLinePoints()); Vector endPoints = flipVector(startPoints); boolean a = lineUp(startShapes, startPoints, 0, 0); boolean b = lineUp(endShapes, endPoints, 0, 0); if (!a || !b) { return; } // G.Mueller change begin if (lineType.equals("-.")) { g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } else if (lineType.equals(".-")) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } else if (lineType.equals(LineType.SOLID.getValue())) { g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } else if (lineType.equals(LineType.DASHED.getValue())) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } else if (lineType.equals(LineType.DOTTED.getValue())) { g2.setStroke(Utils.getStroke(LineType.DOTTED, 1)); } else if (lineType.equals(LineType.DOUBLE.getValue())) { g2.setStroke(Utils.getStroke(LineType.DOUBLE, 1)); } else if (lineType.equals(LineType.DOUBLE_DASHED.getValue())) { g2.setStroke(Utils.getStroke(LineType.DOUBLE_DASHED, 1)); } else if (lineType.equals(LineType.DOUBLE_DOTTED.getValue())) { g2.setStroke(Utils.getStroke(LineType.DOUBLE_DOTTED, 1)); } for (int i = 0; i < getLinePoints().size() - 1; i++) { if (i == Math.floor((getLinePoints().size() - 1) / 2.0)) { Point p1 = getLinePoints().elementAt(i); Point p2 = getLinePoints().elementAt(i + 1); // G.Mueller start Point pm = new Point(p1.x - (p1.x - p2.x) / 2, p1.y - (p1.y - p2.y) / 2); g2.drawLine(p1.x, p1.y, pm.x, pm.y); if (lineType.equals("-.")) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } if (lineType.equals(".-")) { g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } g2.drawLine(pm.x, pm.y, p2.x, p2.y); // g2.drawLine(p1.x, p1.y, p2.x, p2.y); // G. Mueller end // ########################################################################################## // ########################################################################################## if (eerRelDir.indexOf("EER_SUBCLASS") >= 0) { Point px1 = getLinePoints().elementAt(i); Point px2 = getLinePoints().elementAt(i + 1); Point mitte = new Point(px1.x - (px1.x - px2.x) / 2, px1.y - (px1.y - px2.y) / 2); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = mitte.x; int cy = mitte.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 2)); g2.drawArc(mitte.x, mitte.y - (int) (10 * zoom), (int) (20 * zoom), (int) (20 * zoom), 90, 180); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); g2.setTransform(at); } else if (eerRelDir.indexOf("EER") >= 0) { Point px1 = getLinePoints().elementAt(i); Point px2 = getLinePoints().elementAt(i + 1); Point mitte = new Point(px1.x - (px1.x - px2.x) / 2, px1.y - (px1.y - px2.y) / 2); int recSize = (int) (20 * zoom); Point r1 = new Point(mitte.x, mitte.y - recSize); Point r2 = new Point(mitte.x + recSize, mitte.y); Point r3 = new Point(mitte.x, mitte.y + recSize); Point r4 = new Point(mitte.x - recSize, mitte.y); Polygon po1 = new Polygon(); po1.addPoint(r1.x, r1.y); po1.addPoint(r2.x, r2.y); po1.addPoint(r3.x, r3.y); Polygon po2 = new Polygon(); po2.addPoint(r1.x, r1.y); po2.addPoint(r3.x, r3.y); po2.addPoint(r4.x, r4.y); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = mitte.x; int cy = mitte.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); if (eerRelDir.equals("EER1")) { g2.setColor(fgColor); g2.fillPolygon(po1); g2.fillPolygon(po2); } else if (eerRelDir.equals("EER2")) { g2.setColor(bgColor); g2.fillPolygon(po2); g2.setColor(fgColor); g2.fillPolygon(po1); } else if (eerRelDir.equals("EER3")) { g2.setColor(bgColor); g2.fillPolygon(po1); g2.setColor(fgColor); g2.fillPolygon(po2); } g2.setColor(fgColor); g2.draw(po1); g2.draw(po2); g2.setTransform(at); } // A.Mueller start else if (clientServer != null && clientServer.indexOf("rovide") >= 0) { Point px1 = getLinePoints().elementAt(i); Point px2 = getLinePoints().elementAt(i + 1); Point mitte = new Point(px1.x - (px1.x - px2.x) / 2, px1.y - (px1.y - px2.y) / 2); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = mitte.x; int cy = mitte.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); Point outerArc = new Point(mitte.x - (int) (15 * zoom), mitte.y - (int) (15 * zoom)); Point innerCircle = new Point(); g2.setColor(Color.white); g2.fillOval(outerArc.x, outerArc.y, (int) (30 * zoom), (int) (30 * zoom)); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); if (clientServer.equals("provideRequire")) { g2.drawArc(outerArc.x, outerArc.y, (int) (30 * zoom), (int) (30 * zoom), 90, 180); innerCircle = new Point(mitte.x - (int) (5 * zoom), mitte.y - (int) (10 * zoom)); } else if (clientServer.equals("requireProvide")) { g2.drawArc(outerArc.x, outerArc.y, (int) (30 * zoom), (int) (30 * zoom), 90, -180); innerCircle = new Point(mitte.x - (int) (15 * zoom), mitte.y - (int) (10 * zoom)); } g2.drawOval(innerCircle.x, innerCircle.y, (int) (20 * zoom), (int) (20 * zoom)); g2.setTransform(at); } // A.Mueller end // G.Mueller start else if (middleArrow.startsWith("delegation")) { Point px1 = getLinePoints().elementAt(i); Point px2 = getLinePoints().elementAt(i + 1); Point mitte = new Point(px1.x - (px1.x - px2.x) / 2, px1.y - (px1.y - px2.y) / 2); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = mitte.x; int cy = mitte.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); Point circle = new Point(mitte.x - (int) (15 * zoom), mitte.y - (int) (15 * zoom)); if (middleArrow.equals("delegation")) { g2.setColor(Color.white); g2.fillOval(circle.x + (int) (5 * zoom), circle.y + (int) (5 * zoom), (int) (20 * zoom), (int) (20 * zoom)); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); g2.drawOval(circle.x + (int) (5 * zoom), circle.y + (int) (5 * zoom), (int) (20 * zoom), (int) (20 * zoom)); } if (middleArrow.startsWith("delegationArrow")) { g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); if (middleArrow.equals("delegationArrowRight")) { g2.drawLine(circle.x + (int) (5 * zoom), circle.y + (int) (15 * zoom), circle.x - (int) (5 * zoom), circle.y + (int) (9 * zoom)); g2.drawLine(circle.x + (int) (5 * zoom), circle.y + (int) (15 * zoom), circle.x - (int) (5 * zoom), circle.y + (int) (20 * zoom)); } if (middleArrow.equals("delegationArrowLeft")) { g2.drawLine(circle.x + (int) (25 * zoom), circle.y + (int) (15 * zoom), circle.x + (int) (35 * zoom), circle.y + (int) (9 * zoom)); g2.drawLine(circle.x + (int) (25 * zoom), circle.y + (int) (15 * zoom), circle.x + (int) (35 * zoom), circle.y + (int) (20 * zoom)); } g2.setColor(Color.white); g2.fillOval(circle.x + (int) (5 * zoom), circle.y + (int) (5 * zoom), (int) (20 * zoom), (int) (20 * zoom)); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); g2.drawOval(circle.x + (int) (5 * zoom), circle.y + (int) (5 * zoom), (int) (20 * zoom), (int) (20 * zoom)); } if (middleArrow.equals("delegationStart")) { g2.setColor(Color.white); g2.fillArc(circle.x, circle.y, (int) (30 * zoom), (int) (30 * zoom), 90, 180); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); g2.drawArc(circle.x, circle.y, (int) (30 * zoom), (int) (30 * zoom), 90, 180); } if (middleArrow.equals("delegationEnd")) { g2.setColor(Color.white); g2.fillArc(circle.x, circle.y, (int) (30 * zoom), (int) (30 * zoom), 90, -180); g2.setColor(fgColor); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); g2.drawArc(circle.x, circle.y, (int) (30 * zoom), (int) (30 * zoom), 90, -180); } g2.setTransform(at); } // G.Mueller end // ########################################################################################## // ########################################################################################## if (lineType.equals("-.")) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } if (lineType.equals(".-")) { g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } } else { Point p1 = getLinePoints().elementAt(i); Point p2 = getLinePoints().elementAt(i + 1); g2.drawLine(p1.x, p1.y, p2.x, p2.y); } } g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { for (int i = 0; i < getLinePoints().size(); i++) { Point p = getLinePoints().elementAt(i); int start = (int) (SELECTCIRCLESIZE / 15 * 10 * zoom); int width = (int) (SELECTCIRCLESIZE / 15 * 20 * zoom); g2.drawOval(p.x - start, p.y - start, width, width); } // DRAW Moveall Rect Polygon poly = getWholeLinePolygon(); if (poly != null) { g2.drawPolygon(poly); } } Vector tmp = new Vector(startShapes); tmp.addAll(endShapes); for (int i = 0; i < tmp.size(); i++) { Rectangle r = tmp.elementAt(i); if (r instanceof Qualifier) { Qualifier q = (Qualifier) r; // begin B. Buckl g.setColor(bgColor); g.fillRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); g.setColor(fgColor); // end g.drawRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); Main.getHandlerForElement(this).getFontHandler().writeText(g2, q.getString(), r.getX() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), r.getY() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), AlignHorizontal.LEFT); } else if (r instanceof Arrow) { Arrow arrow = (Arrow) r; if (arrow.getString().equals("crowsFoot")) { g2.drawLine(arrow.getX(), arrow.getY() + arrow.getArrowEndA().y, arrow.getX() + arrow.getArrowEndA().x, arrow.getY()); g2.drawLine(arrow.getX(), arrow.getY() + arrow.getArrowEndB().y, arrow.getX() + arrow.getArrowEndB().x, arrow.getY()); // A.Mueller Start } else if (!arrow.getString().equals("n") && !arrow.getString().equals("require") && !arrow.getString().equals("provide") && !arrow.getString().startsWith("package") && !arrow.getString().startsWith("comp")) { // A.Mueller end g2.drawLine(arrow.getX(), arrow.getY(), arrow.getX() + arrow.getArrowEndA().x, arrow.getY() + arrow.getArrowEndA().y); g2.drawLine(arrow.getX(), arrow.getY(), arrow.getX() + arrow.getArrowEndB().x, arrow.getY() + arrow.getArrowEndB().y); // A.Mueller start } // A.Mueller end if (arrow.getString().equals("<<<")) { // LME // filled arrow head int[] ax = new int[3]; int[] ay = new int[3]; ax[0] = arrow.getX(); ax[1] = arrow.getX() + arrow.getArrowEndA().x; ax[2] = arrow.getX() + arrow.getArrowEndB().x; ay[0] = arrow.getY(); ay[1] = arrow.getY() + arrow.getArrowEndA().y; ay[2] = arrow.getY() + arrow.getArrowEndB().y; Polygon myPg = new Polygon(ax, ay, 3); g2.fill(myPg); g2.draw(myPg); } else if (arrow.getString().equals("<<")) { // begin B. Buckl int[] ax = new int[3]; int[] ay = new int[3]; ax[0] = arrow.getX(); ax[1] = arrow.getX() + arrow.getArrowEndA().x; ax[2] = arrow.getX() + arrow.getArrowEndB().x; ay[0] = arrow.getY(); ay[1] = arrow.getY() + arrow.getArrowEndA().y; ay[2] = arrow.getY() + arrow.getArrowEndB().y; Polygon myPg = new Polygon(ax, ay, 3); g2.setColor(bgColor); g2.fill(myPg); g2.setColor(fgColor); g2.draw(myPg); // g2.drawLine((int)arrow.getX()+(int)arrow.getArrowEndA().x, // (int)arrow.getY()+(int)arrow.getArrowEndA().y, // (int)arrow.getX()+(int)arrow.getArrowEndB().x, // (int)arrow.getY()+(int)arrow.getArrowEndB().y); } // end B. Buckl else if (arrow.getString().equals("x")) { int[] ax = new int[4]; int[] ay = new int[4]; ax[0] = arrow.getX(); ay[0] = arrow.getY(); ax[1] = arrow.getX() + arrow.getArrowEndA().x; ay[1] = arrow.getY() + arrow.getArrowEndA().y; ax[3] = arrow.getX() + arrow.getArrowEndB().x; ay[3] = arrow.getY() + arrow.getArrowEndB().y; ax[2] = -arrow.getX() + ax[1] + ax[3]; ay[2] = -arrow.getY() + ay[1] + ay[3]; // begin B. Buckl Polygon myPg = new Polygon(ax, ay, 4); g2.setColor(bgColor); g2.fill(myPg); g2.setColor(fgColor); g2.draw(myPg); // end B. Buckl } else if (arrow.getString().equals("X")) { int[] ax = new int[4]; int[] ay = new int[4]; ax[0] = arrow.getX(); ay[0] = arrow.getY(); ax[1] = arrow.getX() + arrow.getArrowEndA().x; ay[1] = arrow.getY() + arrow.getArrowEndA().y; ax[3] = arrow.getX() + arrow.getArrowEndB().x; ay[3] = arrow.getY() + arrow.getArrowEndB().y; ax[2] = -arrow.getX() + ax[1] + ax[3]; ay[2] = -arrow.getY() + ay[1] + ay[3]; g2.fill(new Polygon(ax, ay, 4)); } // A.Mueller Begin else if (arrow.getString().equals("n")) { Point a1 = arrow.getCrossEndA(); Point a2 = arrow.getCrossEndB(); g2.drawLine(arrow.getX() + arrow.getArrowEndA().x, arrow.getY() + arrow.getArrowEndA().y, arrow.getX() + a2.x, arrow.getY() + a2.y); g2.drawLine(arrow.getX() + arrow.getArrowEndB().x, arrow.getY() + arrow.getArrowEndB().y, arrow.getX() + a1.x, arrow.getY() + a1.y); } else if (arrow.getString().equals("require")) { int width = arrow.getCrossEndB().x - arrow.getCrossEndA().x; int height = arrow.getCrossEndB().y - arrow.getCrossEndA().y; g2.drawOval(arrow.getX() + arrow.getCrossEndA().x, arrow.getY() + arrow.getCrossEndA().y, width, height); } else if (arrow.getString().equals("provide")) { int width = arrow.getCrossEndB().x - arrow.getCrossEndA().x; int height = arrow.getCrossEndB().y - arrow.getCrossEndA().y; g2.drawArc(arrow.getX() + arrow.getCrossEndA().x, arrow.getY() + arrow.getCrossEndA().y, width, height, arrow.getArcStart(), arrow.getArcEnd()); // A.Mueller End // G.Mueller Start } else if (arrow.getString().startsWith("package")) { Point px1; Point px2; if (arrow.getString().equals("packageStart")) { px1 = getStartPoint(); px2 = getLinePoints().elementAt(1); } else { px1 = getEndPoint(); px2 = getLinePoints().elementAt( getLinePoints().size() - 2); } AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = px1.x; int cy = px1.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); g2.setColor(bgColor); g2.fillOval(px1.x, px1.y - (int) (10 * zoom), (int) (20 * zoom), (int) (20 * zoom)); g2.setColor(fgColor); g2.drawOval(px1.x, px1.y - (int) (10 * zoom), (int) (20 * zoom), (int) (20 * zoom)); g2.drawLine(px1.x + (int) (10 * zoom), px1.y - (int) (5 * zoom), px1.x + (int) (10 * zoom), px1.y + (int) (5 * zoom)); g2.drawLine(px1.x + (int) (15 * zoom), px1.y, px1.x + (int) (5 * zoom), px1.y); g2.setTransform(at); // *** // Wirrer G. Start } else if (arrow.getString().startsWith("fill_poly")) { Point px1; Point px2; if (beginArrow.startsWith("fill_poly_start")) { px1 = getStartPoint(); px2 = getLinePoints().elementAt(1); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, px1.x, px1.y); g2.setTransform(at2); int[] x_cord = { px1.x, px1.x + (int) (13 * zoom), px1.x + (int) (13 * zoom) }; int[] y_cord = { px1.y, px1.y - (int) (7 * zoom), px1.y + (int) (7 * zoom) }; Polygon x = new Polygon(x_cord, y_cord, 3); g2.fillPolygon(x); g2.setTransform(at); } if (endArrow.startsWith("fill_poly_end")) { px1 = getEndPoint(); px2 = getLinePoints().elementAt(getLinePoints().size() - 2); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); double winkel = Utils.getAngle(px2.x, px2.y, px1.x, px1.y); at2.rotate(winkel, px1.x, px1.y); g2.setTransform(at2); int[] x_cord = { px1.x, px1.x - (int) (13 * zoom), px1.x - (int) (13 * zoom) }; int[] y_cord = { px1.y, px1.y - (int) (7 * zoom), px1.y + (int) (7 * zoom) }; Polygon x = new Polygon(x_cord, y_cord, 3); g2.fillPolygon(x); g2.setTransform(at); } // Wirrer G. End } else if (arrow.getString().startsWith("comp")) { Point px1; Point px2; int s; int boxSize = (int) (20 * zoom); // we use 5.9 and 6.9 instead of 6 and 7 to get bigger arrows if we zoom out but smaller if gridsize is 10 int arrowOneSize = (int) (5.9 * zoom); int arrowTwoSize = (int) (6.9 * zoom); int arrowTwoSeparator = (int) (2.4 * zoom); int arrowThreeSize = (int) (6 * zoom); int arrowThreeLength = (int) (12 * zoom); // if (beginCSDArrow.equals("compStart")) { if (beginArrow.startsWith("compStart")) { Main.getHandlerForElement(this).getFontHandler().setFontSize((double) 10); s = boxSize; if (!csdStartText.equals("")) { s = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(csdStartText); } if (s < boxSize) { s = boxSize; } px1 = getStartPoint(); px2 = getLinePoints().elementAt(1); g2.setColor(bgColor); g2.fillRect(px1.x - s / 2, px1.y - s / 2, s, s); g2.setColor(fgColor); g2.drawRect(px1.x - s / 2, px1.y - s / 2, s, s); if (csdStartText.equals(">")) { int[] tmpX = { px1.x - arrowOneSize, px1.x + arrowOneSize, px1.x - arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdStartText.equals("<")) { int[] tmpX = { px1.x + arrowOneSize, px1.x - arrowOneSize, px1.x + arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdStartText.equals("v")) { int[] tmpX = { px1.x - arrowOneSize, px1.x, px1.x + arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y + arrowOneSize, px1.y - arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdStartText.equals("^")) { int[] tmpX = { px1.x - arrowOneSize, px1.x, px1.x + arrowOneSize }; int[] tmpY = { px1.y + arrowOneSize, px1.y - arrowOneSize, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdStartText.equals("=")) { g2.drawLine(px1.x - arrowTwoSize, px1.y - arrowTwoSeparator, px1.x + arrowTwoSize, px1.y - arrowTwoSeparator); g2.drawLine(px1.x + arrowTwoSize, px1.y - arrowTwoSeparator, px1.x + 1, px1.y - arrowTwoSize); g2.drawLine(px1.x - arrowTwoSize, px1.y + arrowTwoSeparator, px1.x + arrowTwoSize, px1.y + arrowTwoSeparator); g2.drawLine(px1.x - arrowTwoSize, px1.y + arrowTwoSeparator, px1.x - 1, px1.y + arrowTwoSize); } else { if (!csdStartText.equals("")) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, csdStartText, px1.x, px1.y + (int) (6 * zoom), AlignHorizontal.CENTER); } } if (beginArrow.equals("compStartdel")) { AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = px1.x; int cy = px1.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); g2.drawLine((int) (px1.x + s / 2 + 2 * zoom), px1.y, px1.x + s / 2 + arrowThreeLength, px1.y - arrowThreeSize); g2.drawLine((int) (px1.x + s / 2 + 2 * zoom), px1.y, px1.x + s / 2 + arrowThreeLength, px1.y + arrowThreeSize); g2.setTransform(at); } Main.getHandlerForElement(this).getFontHandler().resetFontSize(); } // if (endCSDArrow.equals("compEnd")) { if (endArrow.startsWith("compEnd")) { Main.getHandlerForElement(this).getFontHandler().setFontSize(10.0); s = boxSize; if (!csdEndText.equals("")) { s = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(csdEndText); } if (s < boxSize) { s = boxSize; } px1 = getEndPoint(); px2 = getLinePoints().elementAt( getLinePoints().size() - 2); g2.setColor(bgColor); g2.fillRect(px1.x - s / 2, px1.y - s / 2, s, s); g2.setColor(fgColor); g2.drawRect(px1.x - s / 2, px1.y - s / 2, s, s); if (csdEndText.equals(">")) { int[] tmpX = { px1.x - arrowOneSize, px1.x + arrowOneSize, px1.x - arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdEndText.equals("<")) { int[] tmpX = { px1.x + arrowOneSize, px1.x - arrowOneSize, px1.x + arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdEndText.equals("v")) { int[] tmpX = { px1.x - arrowOneSize, px1.x, px1.x + arrowOneSize }; int[] tmpY = { px1.y - arrowOneSize, px1.y + arrowOneSize, px1.y - arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdEndText.equals("^")) { int[] tmpX = { px1.x - arrowOneSize, px1.x, px1.x + arrowOneSize }; int[] tmpY = { px1.y + arrowOneSize, px1.y - arrowOneSize, px1.y + arrowOneSize }; g2.fillPolygon(tmpX, tmpY, 3); } else if (csdEndText.equals("=")) { g2.drawLine(px1.x - arrowTwoSize, px1.y - arrowTwoSeparator, px1.x + arrowTwoSize, px1.y - arrowTwoSeparator); g2.drawLine(px1.x + arrowTwoSize, px1.y - arrowTwoSeparator, px1.x + 1, px1.y - arrowTwoSize); g2.drawLine(px1.x - arrowTwoSize, px1.y + arrowTwoSeparator, px1.x + arrowTwoSize, px1.y + arrowTwoSeparator); g2.drawLine(px1.x - arrowTwoSize, px1.y + arrowTwoSeparator, px1.x - 1, px1.y + arrowTwoSize); } else { if (!csdEndText.equals("")) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, csdEndText, px1.x, px1.y + (int) (6 * zoom), AlignHorizontal.CENTER); } } if (endArrow.equals("compEnddel")) { AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); int cx = px1.x; int cy = px1.y; double winkel = Utils.getAngle(px1.x, px1.y, px2.x, px2.y); at2.rotate(winkel, cx, cy); g2.setTransform(at2); g2.drawLine((int) (px1.x + s / 2 + 2 * zoom), px1.y, px1.x + s / 2 + arrowThreeLength, px1.y - arrowThreeSize); g2.drawLine((int) (px1.x + s / 2 + 2 * zoom), px1.y, px1.x + s / 2 + arrowThreeLength, px1.y + arrowThreeSize); g2.setTransform(at); } Main.getHandlerForElement(this).getFontHandler().resetFontSize(); } } // G.Mueller End } else if (r instanceof Multiplicity) { Multiplicity m = (Multiplicity) r; // g.drawRect((int)r.getX(), (int)r.getY(), (int)r.getWidth(), // (int)r.getHeight()); Main.getHandlerForElement(this).getFontHandler().writeText(g2, m.getString(), r.getX(), r.getY() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + 2 * (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), AlignHorizontal.LEFT); // B. Buckl // added // +2*this.getHandler().getDistTextToText() } else if (r instanceof Role) { Role role = (Role) r; String str = role.getString(); int position = 0; int y = 4 * (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); while (position != -1) { position = str.indexOf("\\\\"); if (position != -1) { String s = str.substring(0, position); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, r.getX(), r.getY() + y, AlignHorizontal.LEFT); y = y + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); str = str.substring(position + 2, str.length()); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, str, r.getX(), r.getY() + y, AlignHorizontal.LEFT); } } // /* this.getHandler().write(g2, role.getString(), (int) r.getX(), (int) r .getY() + this.getHandler().getFontHandler().getFontsize() + 2 this.getHandler().getDistTextToText(), false); // B. Buckl // added // +2*this.getHandler().getDistTextToText() */ // // A.Mueller end // G.Mueller Start } else if (r instanceof Port) { Port p = (Port) r; Main.getHandlerForElement(this).getFontHandler().writeText(g2, p.getString(), r.getX(), r.getY(), AlignHorizontal.LEFT); } // G.Mueller end } if (getStrings() != null) { if (getStrings().size() > 0) { Point start = getCenterOfLine(); int yPos = start.y - (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); // B. Buckl // added // -this.getHandler().getDistTextToText() int xPos = start.x; for (int i = 0; i < getStrings().size(); i++) { String s = getStrings().elementAt(i); // A.Mueller Begin... if (s.startsWith(">") || s.endsWith(">") || s.startsWith("<") || s.endsWith("<")) { // starts or ends with an arrow, check if it is the only // one.. if (s.indexOf(">") == s.lastIndexOf(">") && s.indexOf(">") != -1 || s.indexOf("<") == s.lastIndexOf("<") && s.indexOf("<") != -1) { // decide where and what to draw... int fontHeight = g2.getFontMetrics( Main.getHandlerForElement(this).getFontHandler().getFont()).getHeight() - g2.getFontMetrics(Main.getHandlerForElement(this).getFontHandler().getFont()).getDescent() - g2.getFontMetrics(Main.getHandlerForElement(this).getFontHandler().getFont()).getLeading(); fontHeight = fontHeight / 3 * 2; if (s.endsWith(">")) { s = s.substring(0, s.length() - 1); int fontWidth = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(s); xPos = xPos - (fontHeight + 4) / 2; int startDrawX = xPos + fontWidth / 2 + 4; Polygon temp = new Polygon(); temp.addPoint(startDrawX, yPos); temp.addPoint(startDrawX, yPos - fontHeight); temp.addPoint(startDrawX + fontHeight - 1, yPos - fontHeight / 2); g2.fillPolygon(temp); } else if (s.endsWith("<")) { s = s.substring(0, s.length() - 1); int fontWidth = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(s); xPos = xPos - (fontHeight + 4) / 2; int startDrawX = xPos + fontWidth / 2 + 4; Polygon temp = new Polygon(); temp.addPoint(startDrawX + fontHeight - 1, yPos); temp.addPoint(startDrawX + fontHeight - 1, yPos - fontHeight); temp.addPoint(startDrawX, yPos - fontHeight / 2); g2.fillPolygon(temp); } else if (s.startsWith(">")) { s = s.substring(1, s.length()); int fontWidth = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(s); xPos = xPos + (fontHeight + 4) / 2; int startDrawX = xPos - fontWidth / 2 - 4; Polygon temp = new Polygon(); temp.addPoint(startDrawX - fontHeight + 1, yPos); temp.addPoint(startDrawX - fontHeight + 1, yPos - fontHeight); temp.addPoint(startDrawX, yPos - fontHeight / 2); g2.fillPolygon(temp); } else if (s.startsWith("<")) { s = s.substring(1, s.length()); int fontWidth = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(s); xPos = xPos + (fontHeight + 4) / 2; int startDrawX = xPos - fontWidth / 2 - 4; Polygon temp = new Polygon(); temp.addPoint(startDrawX, yPos); temp.addPoint(startDrawX, yPos - fontHeight); temp.addPoint(startDrawX - fontHeight + 1, yPos - fontHeight / 2); g2.fillPolygon(temp); } } } // A.Mueller end... Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, xPos, yPos, AlignHorizontal.CENTER); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } } // The criticalPoints must be calculated to expand the relations size by the associated relation-text Vector criticalPoints = new Vector(); for (int i = 1; i < startShapes.size(); i++) { Rectangle r = startShapes.elementAt(i); Point p1 = new Point(r.getX() - (int) (2 * zoom), r.getY() - (int) (2 * zoom)); Point p2 = new Point(r.getX() + r.getWidth() + (int) (2 * zoom), r.getY() + r.getHeight() + (int) (2 * zoom)); criticalPoints.add(p1); criticalPoints.add(p2); } for (int i = 1; i < endShapes.size(); i++) { Rectangle r = endShapes.elementAt(i); Point p1 = new Point(r.getX() - (int) (2 * zoom), r.getY() - (int) (2 * zoom)); Point p2 = new Point(r.getX() + r.getWidth() + (int) (2 * zoom), r.getY() + r.getHeight() + (int) (2 * zoom)); criticalPoints.add(p1); criticalPoints.add(p2); } if (getStrings() != null) { if (getStrings().size() > 0) { Point start = getCenterOfLine(); int yPos = start.y; int xPos = start.x; for (int i = 0; i < getStrings().size(); i++) { String s = getStrings().elementAt(i); int width = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(s); criticalPoints.add(new Point(xPos - width / 2 - (int) (20 * zoom), yPos - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() - (int) (20 * zoom))); criticalPoints.add(new Point(xPos + width / 2 + (int) (20 * zoom), yPos + (int) (20 * zoom))); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } } /** * Change Size of relation to fit the relations size * Must be made to resize the relation automatically during draging an endpoint */ // (minx,miny) is the upper left end and (maxx,maxy) is the lower right end of the relation int minx = Integer.MAX_VALUE; int miny = Integer.MAX_VALUE; int maxx = Integer.MIN_VALUE; int maxy = Integer.MIN_VALUE; for (int i = 0; i < getLinePoints().size(); i++) { Point p = getLinePoints().elementAt(i); minx = Math.min(minx, p.x); miny = Math.min(miny, p.y); maxx = Math.max(maxx, p.x); maxy = Math.max(maxy, p.y); // Subtract or add the SELECTCIRCLESIZE to avoid cutting the circles at the end of the relation minx = (int) Math.min(minx, p.x - SELECTCIRCLESIZE * zoom); miny = (int) Math.min(miny, p.y - SELECTCIRCLESIZE * zoom); maxx = (int) Math.max(maxx, p.x + SELECTCIRCLESIZE * zoom); maxy = (int) Math.max(maxy, p.y + SELECTCIRCLESIZE * zoom); } for (int i = 0; i < criticalPoints.size(); i++) { Point p = criticalPoints.elementAt(i); minx = Math.min(minx, p.x); miny = Math.min(miny, p.y); maxx = Math.max(maxx, p.x); maxy = Math.max(maxy, p.y); } // BUGFIX ZOOM: We must consider the gridsize for the min and max value to avoid rounding errors // Therefore we subtract or add the difference to the next possible value int gridSize = Main.getHandlerForElement(this).getGridSize(); minx -= minx % gridSize; miny -= miny % gridSize; // Subtract gridSize another time to avoid a too small selection area for the relation-selection circle minx -= gridSize; miny -= gridSize; maxx += maxx % gridSize; maxy += maxy % gridSize; if (maxx != 0 || maxy != 0) { int diffx = maxx - getRectangle().width; int diffy = maxy - getRectangle().height; this.setSize(getRectangle().width + diffx, getRectangle().height + diffy); } if (minx != 0 | miny != 0) { setLocationDifference(minx, miny); this.setSize(getRectangle().width + -minx, getRectangle().height + -miny); for (int i = 0; i < getLinePoints().size(); i++) { Point p = getLinePoints().elementAt(i); p.x += -minx; p.y += -miny; } } } private Point getStartPoint() { Point ret = getLinePoints().elementAt(0); return ret; } private Point getEndPoint() { Point ret = getLinePoints().elementAt( getLinePoints().size() - 1); return ret; } public PointDouble getAbsoluteCoorStart() { PointDouble ret = new PointDouble(getRectangle().x + getStartPoint().x, getRectangle().y + getStartPoint().y); return ret; } public PointDouble getAbsoluteCoorEnd() { PointDouble ret = new PointDouble(getRectangle().x + getEndPoint().x, getRectangle().y + getEndPoint().y); return ret; } // G.Mueller start public String[] getCSDText(String str) { // for the Composite Structure Diagram Text String[] tmp = new String[4]; int to = 0; int from = 0; tmp[0] = " "; tmp[1] = " "; tmp[2] = " "; tmp[3] = " "; if (str.length() > 3) { // if (str.indexOf("<[") >=3) tmp[2] = // str.substring(3,str.indexOf("<[")); // if (str.lastIndexOf("[") >=3 && str.lastIndexOf("[")-1 != // str.lastIndexOf("<[")) tmp[3] = str.substring(str.indexOf("[", // str.length())); from = str.indexOf("<[") + 2; if (from >= 2) { to = str.indexOf("]"); } if (from >= 2 && to >= 0 && from < to) { tmp[0] = str.substring(from, to); } from = str.indexOf("[", to) + 1; if (from >= 1) { to = str.indexOf("]>", to); } if (from >= 1 && to >= 0 && from < to) { tmp[1] = str.substring(from, to); } } return tmp; } // G.Mueller end @Override public StickingPolygon generateStickingBorder() { // LME return NoStickingPolygonGenerator.INSTANCE.generateStickingBorder(getRectangle()); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { return NoStickingPolygonGenerator.INSTANCE.generateStickingBorder(getRectangle()); } public boolean allPointsOnSamePos() { Point first = null; for (Point p : getLinePoints()) { if (first == null) { first = p; } else { if (first.x != p.x || first.y != p.y) { return false; } } } return true; } @Override protected Color getDefaultBackgroundColor() { return Converter.convert(ColorOwn.WHITE); } @Override public Set getResizeArea(int x, int y) { return Collections. emptySet(); } @Override public Integer getLayer() { return getLayerHelper(LayerFacet.DEFAULT_VALUE_RELATION); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Component.java0000644000175000017500000001066412533641120026242 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Component extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); boolean normal = false; // G.M // symbol outline g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = 0; int startY = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.startsWith("'") || normal) { // G.M startY = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); s = s.substring(1, s.length()); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (10 * zoom), startY + yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); normal = true; } else { if (s.startsWith("*")) { startY = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); s = s.substring(1, s.length()); } yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, startY + yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } // small component symbol g2.drawLine(getRectangle().width - (int) (50 * zoom), (int) (10 * zoom), getRectangle().width - (int) (15 * zoom), (int) (10 * zoom)); g2.drawLine(getRectangle().width - (int) (50 * zoom), (int) (35 * zoom), getRectangle().width - (int) (15 * zoom), (int) (35 * zoom)); g2.drawLine(getRectangle().width - (int) (15 * zoom), (int) (10 * zoom), getRectangle().width - (int) (15 * zoom), (int) (35 * zoom)); g2.drawLine(getRectangle().width - (int) (50 * zoom), (int) (10 * zoom), getRectangle().width - (int) (50 * zoom), (int) (15 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (15 * zoom), getRectangle().width - (int) (45 * zoom), (int) (15 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (20 * zoom), getRectangle().width - (int) (45 * zoom), (int) (20 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (15 * zoom), getRectangle().width - (int) (55 * zoom), (int) (20 * zoom)); g2.drawLine(getRectangle().width - (int) (45 * zoom), (int) (15 * zoom), getRectangle().width - (int) (45 * zoom), (int) (20 * zoom)); g2.drawLine(getRectangle().width - (int) (50 * zoom), (int) (20 * zoom), getRectangle().width - (int) (50 * zoom), (int) (25 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (25 * zoom), getRectangle().width - (int) (45 * zoom), (int) (25 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (30 * zoom), getRectangle().width - (int) (45 * zoom), (int) (30 * zoom)); g2.drawLine(getRectangle().width - (int) (55 * zoom), (int) (25 * zoom), getRectangle().width - (int) (55 * zoom), (int) (30 * zoom)); g2.drawLine(getRectangle().width - (int) (45 * zoom), (int) (25 * zoom), getRectangle().width - (int) (45 * zoom), (int) (30 * zoom)); g2.drawLine(getRectangle().width - (int) (50 * zoom), (int) (30 * zoom), getRectangle().width - (int) (50 * zoom), (int) (35 * zoom)); } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Taxonomy_of_Workprocesses.javaumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Taxonomy_of_Workprocesses.j0000644000175000017500000001151412533641120031036 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Taxonomy_of_Workprocesses extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int level = 0; double yPos = 10 * zoom; double xPos = 10 * zoom; double dist = 10 * Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); double ovalHeight = 3 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); double ovalWidth = 10 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); Point nextDock = new Point((int) (xPos + ovalWidth / 2 + 0.5), (int) (ovalHeight + yPos + 0.5)); Vector dock = new Vector(); dock.add(nextDock); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); int currentLineLevel = calculateLevel(s); s = s.replaceAll("\t", ""); if (currentLineLevel > level && i > 0) { level++; nextDock = new Point((int) (xPos + ovalWidth / 2 + 0.5), (int) (ovalHeight + yPos + 0.5)); dock.add(nextDock); nextDock = dock.elementAt(level - 1); drawDockAnchor(g2, nextDock); } if (currentLineLevel < level) { level = currentLineLevel; } xPos = 10 * zoom + ovalWidth * level; drawProcess(g2, xPos, yPos, s); if (level > 0) { // change dock color to red if too much tabs occur Color color = g2.getColor(); if (currentLineLevel > level) { g2.setColor(Color.red); } nextDock = dock.elementAt(level - 1); drawDock(g2, nextDock, xPos, yPos); // reset color g2.setColor(color); } nextDock = new Point((int) (xPos + ovalWidth / 2 + 0.5), (int) (yPos + ovalHeight + 0.5)); dock.set(level, nextDock); yPos += 2 * ovalHeight - dist; } } @Override public StickingPolygon generateStickingBorder() { StickingPolygon p = new StickingPolygon(0, 0); return p; } private void drawProcess(Graphics2D g2, double xPos, double yPos, String name) { double zoom = Main.getHandlerForElement(this).getZoomFactor(); double ovalHeight = 3 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); double ovalWidth = 10 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); g2.drawOval((int) (xPos + 0.5), (int) (yPos + 0.5), (int) (ovalWidth + 0.5), (int) (ovalHeight + 0.5)); Main.getHandlerForElement(this).getFontHandler().writeText(g2, name, (int) (xPos + ovalWidth / 2 + 0.5), (int) (yPos + 5 * zoom + ovalHeight / 2 + 0.5), AlignHorizontal.CENTER); } private void drawDock(Graphics2D g2, Point nextDock, double xPos, double yPos) { double zoom = Main.getHandlerForElement(this).getZoomFactor(); double ovalHeight = 3 * Main.getHandlerForElement(this).getFontHandler().getFontSize(); g2.drawLine(nextDock.x, (int) (nextDock.y + 9 * zoom + 0.5), nextDock.x, (int) (ovalHeight / 2 + yPos + 0.5)); g2.drawLine(nextDock.x, (int) (ovalHeight / 2 + yPos + 0.5), (int) (xPos + 0.5), (int) (ovalHeight / 2 + yPos + 0.5)); } private void drawDockAnchor(Graphics2D g2, Point nextDock) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int[] xkanten = { nextDock.x, nextDock.x + (int) (6 * zoom), nextDock.x - (int) (6 * zoom) }; int[] ykanten = { nextDock.y, nextDock.y + (int) (9 * zoom), nextDock.y + (int) (9 * zoom) }; int kanten_zahl = 3; g2.drawPolygon(new Polygon(xkanten, ykanten, kanten_zahl)); } // calculates the hierarchy level according to tab count in the string protected int calculateLevel(String s) { int level = 0; while (s.length() > 0 && s.charAt(0) == '\t') { level++; s = s.substring(1); } // Logger.getAnonymousLogger().info("string=="+s+";index=="+level); return level; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/EER_Rel_Diamond.java0000644000175000017500000000553212533641120027146 0ustar benbenpackage com.baselet.element.old.element; // Some import to have access to more Java features import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class EER_Rel_Diamond extends OldGridElement { // Change this method if you want to edit the graphical // representation of your custom element. @Override public void paintEntity(Graphics g) { // Some unimportant initialization stuff; setting color, font // quality, etc. You should not have to change this. Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); // Finally, change other graphical attributes using // drawLine, getWidth, getHeight.. // Define the elements outline using a polygon, rectangle, oval, etc. Polygon poly = new Polygon(); poly.addPoint(getRectangle().width / 2, 0); poly.addPoint(getRectangle().width - 1, getRectangle().height / 2); poly.addPoint(getRectangle().width / 2, getRectangle().height - 1); poly.addPoint(0, getRectangle().height / 2); g2.setComposite(composites[1]); // set aplha composite for drawing the background color g2.setColor(bgColor); g2.fillPolygon(poly); // fill the background g2.setComposite(composites[0]); // reset composite settings if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } // It's getting interesting here: // First, the strings you type in the element editor are read and // split into lines. Then, by default, they are printed out on the // element, aligned to the left. Change this to modify this default // text printing and to react to special strings (like the "--" string // in the UML class elements which draw a line). Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = getRectangle().height / 2 - ((int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()) * tmp.size() / 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // Draw the elements outline g2.drawPolygon(poly); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Note.java0000644000175000017500000000740612533641120025205 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Note extends OldGridElement { private Vector getStringVector() { return Utils.decomposeStrings(getPanelAttributes()); } @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); // g2.setColor(_activeColor); Composite[] composites = colorize(g2); // enable colors int yPos = 0; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); Vector tmp = getStringVector(); Polygon poly = new Polygon(); poly.addPoint(0, 0); poly.addPoint(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0); poly.addPoint(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0); poly.addPoint(getRectangle().width - 1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); poly.addPoint(getRectangle().width - 1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); poly.addPoint(getRectangle().width - 1, getRectangle().height - 1); poly.addPoint(getRectangle().width - 1, getRectangle().height - 1); poly.addPoint(0, getRectangle().height - 1); poly.addPoint(0, getRectangle().height - 1); poly.addPoint(0, 0); // p.addPoint(this.getWidth()-Constants.getFontsize(),0); p.addPoint(this.getWidth()-Constants.getFontsize(), Constants.getFontsize()); // p.addPoint(this.getWidth()-Constants.getFontsize(),Constants.getFontsize()); p.addPoint(this.getWidth()-1, Constants.getFontsize()); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } g2.drawLine(0, 0, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, getRectangle().width - 1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); g2.drawLine(getRectangle().width - 1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), getRectangle().width - 1, getRectangle().height - 1); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(0, getRectangle().height - 1, 0, 0); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), getRectangle().width - 1, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/RegionEndState.java0000644000175000017500000000231712533641120027147 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class RegionEndState extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); g2.drawOval(0, 0, getRectangle().width - 1, getRectangle().height - 1); AffineTransform at = g2.getTransform(); AffineTransform at2 = (AffineTransform) at.clone(); at2.rotate(Math.toRadians(45), getRectangle().width / 2.0, getRectangle().height / 2.0); g2.setTransform(at2); g2.drawLine(0, getRectangle().height / 2, getRectangle().width, getRectangle().height / 2); g2.drawLine(getRectangle().width / 2, 0, getRectangle().width / 2, getRectangle().height); g2.setTransform(at); } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/UseCase.java0000644000175000017500000000627312533641120025631 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.diagram.DiagramHandler; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class UseCase extends OldGridElement { private Vector getStringVector() { Vector ret = Utils.decomposeStrings(getPanelAttributes()); return ret; } @Override public void paintEntity(Graphics g) { int a = Math.max(1, (getRectangle().width - 1) / 2); int b = (getRectangle().height - 1) / 2; boolean found = false; int x = (getRectangle().width - 1) / 9 * 4; int y = (int) Math.round(Math.sqrt((a * a * b * b - b * b * x * x * 1.0) / (a * a * 1.0))); int yPos = 0; int yPos1 = b; Graphics2D g2 = (Graphics2D) g; DiagramHandler handlerForElement = Main.getHandlerForElement(this); g2.setFont(handlerForElement.getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(bgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillOval(0, 0, 2 * a, 2 * b); g2.setComposite(composites[0]); if (handlerForElement.getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } Vector tmp = new Vector(getStringVector()); if (tmp.contains("lt=.")) { tmp.remove("lt=."); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } g2.drawOval(0, 0, 2 * a, 2 * b); if (tmp.contains("--")) { yPos = (b - y) / 2; g2.drawLine(a - x, b - y, a + x, b - y); found = true; } else { yPos = getRectangle().height / 2 - tmp.size() * (int) (handlerForElement.getFontHandler().getFontSize() + handlerForElement.getFontHandler().getDistanceBetweenTexts()) / 2; } for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--") && found) { yPos = yPos1; } else if (found) { handlerForElement.getFontHandler().writeText(g2, s, a, yPos + 5, AlignHorizontal.CENTER); yPos += 5 * handlerForElement.getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) handlerForElement.getFontHandler().getFontSize(); handlerForElement.getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += handlerForElement.getFontHandler().getDistanceBetweenTexts(); } } g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); // First point is the top left then the points are added clockwise p.addPoint(x + width / 4, y); p.addPoint(x + width * 3 / 4, y); p.addPoint(x + width, y + height / 4); p.addPoint(x + width, y + height * 3 / 4); p.addPoint(x + width * 3 / 4, y + height); p.addPoint(x + width / 4, y + height); p.addPoint(x, y + height * 3 / 4); p.addPoint(x, y + height / 4, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Text.java0000644000175000017500000000224212533641120025215 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Text extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); g2.setColor(fgColor); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/FinalState.java0000644000175000017500000000200312533641120026316 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; /** * @author Ludwig */ @SuppressWarnings("serial") public class FinalState extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); g2.drawOval(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.fillOval((int) (4 * zoom), (int) (4 * zoom), getRectangle().width - (int) (8 * zoom), getRectangle().height - (int) (8 * zoom)); } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Taxonomy_of_Actors.java0000644000175000017500000001210712533641120030107 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Taxonomy_of_Actors extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int level = 0; float yPos = 10 * zoom; float xPos = 10 * zoom; float actorHeight = 60 * zoom; float actorWidth = 14 * zoom; Vector dock = new Vector(); Point nextDock = new Point((int) (xPos + actorWidth / 2 + 0.5), (int) (actorHeight + yPos + 0.5)); dock.add(nextDock); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); int currentLineLevel = calculateLevel(s); s = s.replaceAll("\t", ""); // increase level if (currentLineLevel > level && i > 0) { level++; nextDock = new Point((int) (xPos + actorWidth / 2 + 0.5), (int) (actorHeight + yPos + 0.5)); dock.add(nextDock); nextDock = dock.elementAt(level - 1); drawDockAnchor(g2, nextDock); } // decrease level if (currentLineLevel < level) { level = currentLineLevel; } xPos = 10 * zoom + 4 * actorWidth * level; drawActor(g2, xPos, yPos, s); // draw docks for non root elements if (level > 0) { // change dock color to red if too much tabs occur Color color = g2.getColor(); if (currentLineLevel > level) { g2.setColor(Color.red); } nextDock = dock.elementAt(level - 1); drawDock(g2, nextDock, xPos, yPos); // reset color g2.setColor(color); } nextDock = new Point((int) (xPos + actorWidth / 2 + 0.5), (int) (actorHeight + yPos + 0.5)); dock.set(level, nextDock); yPos += actorHeight; } } @Override public StickingPolygon generateStickingBorder() { StickingPolygon p = new StickingPolygon(0, 0); return p; } private void drawDock(Graphics2D g2, Point nextDock, float xPos, float yPos) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); float dockHeight = 50 * zoom; g2.drawLine(nextDock.x, nextDock.y, nextDock.x, (int) (dockHeight / 2 + yPos + 0.5)); g2.drawLine(nextDock.x, (int) (dockHeight / 2 + yPos + 0.5), (int) (xPos - 4 * zoom + 0.5), (int) (dockHeight / 2 + yPos + 0.5)); } private void drawActor(Graphics2D g2, float xPos, float yPos, String name) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); float head = 14 * zoom; float distance = 10 * zoom; g2.drawOval((int) (xPos + 0.5), (int) (yPos + 0.5), (int) (head + 0.5), (int) (head + 0.5)); g2.drawLine((int) (head / 2 + xPos + 0.5), (int) (head + yPos + 0.5), (int) (head / 2 + xPos + 0.5), (int) (yPos + head * 3 - distance + 0.5)); g2.drawLine((int) (xPos - 4 * zoom + 0.5), (int) (yPos + head + head / 3 + 0.5), (int) (xPos + head + 4 * zoom + 0.5), (int) (yPos + head + head / 3 + 0.5)); g2.drawLine((int) (head / 2 + xPos + 0.5), (int) (yPos + head * 3 - distance + 0.5), (int) (head + xPos + 0.5), (int) (yPos + head * 4 - distance + 0.5)); g2.drawLine((int) (head / 2 + xPos), (int) (yPos + head * 3 - distance + 0.5), (int) (xPos + 0.5), (int) (yPos + head * 4 - distance + 0.5)); // this.getHandler().getFontHandler().writeText(g2, name, xPos, yPos + (int) (4.5*head), false); Main.getHandlerForElement(this).getFontHandler().writeText(g2, name, (int) (xPos + head * 1.5 + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + 0.5), (int) (2 * head + yPos + 0.5), AlignHorizontal.LEFT); } private void drawDockAnchor(Graphics2D g2, Point nextDock) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int[] xkanten = { nextDock.x, nextDock.x + (int) (6 * zoom), nextDock.x - (int) (6 * zoom) }; int[] ykanten = { nextDock.y - (int) (9 * zoom), nextDock.y, nextDock.y }; int kanten_zahl = 3; g2.drawPolygon(new Polygon(xkanten, ykanten, kanten_zahl)); } // calculates the hierarchy level according to tab count in the string protected int calculateLevel(String s) { int level = 0; while (s.length() > 0 && s.charAt(0) == '\t') { level++; s = s.substring(1); } // Logger.getAnonymousLogger().info("string=="+s+";index=="+level); return level; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/EER_Entity.java0000644000175000017500000001135712533641120026247 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class EER_Entity extends OldGridElement { int ySave = 0; boolean hasAttributes = false; private Vector getStringVector() { Vector ret = Utils.decomposeStrings(getPanelAttributes()); return ret; } @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); Vector tmp = getStringVector(); boolean CENTER = true; boolean drawInnerRect = false; int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2; // ### draw rectangles and lines (some duplicated code) Polygon poly = new Polygon(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { CENTER = false; ySave = yPos + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 3; } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER && s.startsWith("##")) { drawInnerRect = true; } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); if (CENTER) { ySave = yPos; } } } poly.addPoint(0, 0); poly.addPoint(getRectangle().width - 1, 0); if (CENTER) { hasAttributes = false; // see getStickingBorder() ySave = getRectangle().height; poly.addPoint(getRectangle().width - 1, getRectangle().height - 1); poly.addPoint(0, getRectangle().height - 1); } else { hasAttributes = true; // see getStickingBorder() g.drawLine((int) (10 * zoom), ySave, (int) (10 * zoom), yPos + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() - (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); poly.addPoint(getRectangle().width - 1, ySave); poly.addPoint(0, ySave); } g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawPolygon(poly); if (drawInnerRect) { if (CENTER) { g.drawRect((int) (3 * zoom), (int) (3 * zoom), getRectangle().width - (int) (7 * zoom), getRectangle().height - (int) (7 * zoom)); } else { g.drawRect((int) (3 * zoom), (int) (3 * zoom), getRectangle().width - (int) (7 * zoom), ySave - (int) (6 * zoom)); } } // #### draw text CENTER = true; yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { CENTER = false; ySave = yPos + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 3; } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER) { String s1 = s; if (s.startsWith("##")) { drawInnerRect = true; s1 = s1.substring(2); } Main.getHandlerForElement(this).getFontHandler().writeText(g2, s1, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); if (CENTER) { ySave = yPos; } } } } // @Override // public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { // StickingPolygon p = new StickingPolygon(0, 0); // p.addPoint(new Point(x, y)); // p.addPoint(new Point(x + width, y)); // p.addPoint(new Point(x + width, y + ySave - 1)); // if (!hasAttributes) p.addPoint(new Point(x, y + ySave - 1), true); // else p.addLine(new Point(x, y + ySave - 1), new Point(x, y)); // return p; // } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SeqSelfMessage.java0000644000175000017500000000754312533641120027151 0ustar benbenpackage com.baselet.element.old.element; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class SeqSelfMessage extends OldGridElement { public SeqSelfMessage() { super(); } @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); float zoom = Main.getHandlerForElement(this).getZoomFactor(); int size_3d = (int) (10 * zoom); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, size_3d, getRectangle().width - size_3d - 1, getRectangle().height - size_3d - 1); Polygon p = new Polygon(); p.addPoint(getRectangle().width - size_3d - 1, getRectangle().height - 1); p.addPoint(getRectangle().width - size_3d - 1, size_3d); p.addPoint(getRectangle().width - 1, 0); p.addPoint(getRectangle().width - 1, getRectangle().height - size_3d - 1); Polygon p1 = new Polygon(); p1.addPoint(0, size_3d); p1.addPoint(size_3d, 0); p1.addPoint(getRectangle().width - 1, 0); p1.addPoint(getRectangle().width - size_3d - 1, size_3d); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); g2.setColor(new Color(230, 230, 230)); g2.fillPolygon(p); g2.fillPolygon(p1); g2.setComposite(composites[0]); g2.setColor(fgColor); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, size_3d, getRectangle().width - size_3d - 1, getRectangle().height - size_3d - 1); // draw polygons by hand to avoid double painted line g2.drawLine(0, size_3d, size_3d, 0); g2.drawLine(size_3d, 0, getRectangle().width - 1, 0); g2.drawLine(getRectangle().width - 1, 0, getRectangle().width - 1, getRectangle().height - size_3d - 1); g2.drawLine(getRectangle().width - 1, getRectangle().height - size_3d - 1, getRectangle().width - size_3d - 1, getRectangle().height - 1); g2.drawLine(getRectangle().width - size_3d - 1, size_3d, getRectangle().width - 1, 0); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); yPos = yPos + size_3d; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (s.startsWith("center:")) { s = s.substring(7); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - size_3d - 1) / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int size_3d = (int) (10 * zoom); StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(x, y + size_3d); p.addPoint(x, y + height); p.addPoint(x + width - size_3d, y + height); p.addPoint(x + width, y + height - size_3d); p.addPoint(x + width, y); p.addPoint(x + size_3d, y, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/TimeSignal.java0000644000175000017500000001055112533641120026327 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.util.HashSet; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.command.OldResize; @SuppressWarnings("serial") public class TimeSignal extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); boolean ADAPT_SIZE = false; int x0, y0, b, h; x0 = (int) (getRectangle().width / 2.0 - 20 * zoom); y0 = 0; b = (int) (getRectangle().width / 2.0 + 20 * zoom); h = (int) (40 * zoom); // g2.drawLine(x0,y0,b,y0); // g2.drawLine(b, h, x0, h); // g2.drawLine(x0,y0,b, h); // g2.drawLine(b,y0,x0, h); Polygon poly = new Polygon(); poly.addPoint(x0, y0); poly.addPoint(b, y0); poly.addPoint(x0, h); poly.addPoint(b, h); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawPolygon(poly); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = 0; yPos += 4 * Main.getHandlerForElement(this).getGridSize(); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.drawLine(getRectangle().width / 2 - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 4, yPos, getRectangle().width / 2 + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 4, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); TextLayout l = new TextLayout(s, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Rectangle2D r2d = l.getBounds(); int width = (int) r2d.getWidth(); int xPos = getRectangle().width / 2 - width / 2; if (xPos < 0) { ADAPT_SIZE = true; break; } Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } if (ADAPT_SIZE) { new OldResize(this, -Main.getHandlerForElement(this).getGridSize(), 0, 0, 0).execute(Main.getHandlerForElement(this)); new OldResize(this, 0, 0, Main.getHandlerForElement(this).getGridSize(), 0).execute(Main.getHandlerForElement(this)); return; } if (yPos > getRectangle().height) { new OldResize(this, 0, 0, 0, 20).execute(Main.getHandlerForElement(this)); return; } } /* public int doesCoordinateAppearToBeConnectedToMe(Point p) { int tmpX=p.x-this.getX()-this.getWidth()/2; int tmpY=p.y-this.getY()-(2*this.getHandler().getMainUnit()+20)/2; if ((tmpX>-4 && tmpX<+4)&&(tmpY>-4 && tmpY<+4)) { return 15; } else return 0; } */ @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); StickingPolygon p = new StickingPolygon(0, 0); int px = x + width / 2; int py = (int) (y + 40 * zoom / 2); p.addPoint(px - 4, py - 4); p.addPoint(px + 4, py - 4); p.addPoint(px + 4, py + 4); p.addPoint(px - 4, py + 4, true); return p; } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Systemborder.java0000644000175000017500000000676612533641120026772 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Systemborder extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); boolean center = false; boolean downleft = false; boolean upcenter = false; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.startsWith("center:") && !s.equals("center:")) { if (tmp.size() == 1) { yPos = (getRectangle().height - 1) / 2 - (int) (10 * zoom); } else { yPos = (getRectangle().height - 1) / 2 - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * (tmp.size() / 2) - (int) (10 * zoom); } center = true; s = s.replace("center:", ""); } else if (s.startsWith("bottomleft:") && !s.equals("bottomleft:")) { downleft = true; s = s.replace("bottomleft:", ""); yPos = getRectangle().height - 1 - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); } else if (s.startsWith("topcenter:") && !s.equals("topcenter:")) { upcenter = true; s = s.replace("topcenter:", ""); // yPos+=this.getHandler().getFontHandler().getFontsize(); } if (center) { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - 1) / 2.0, yPos, AlignHorizontal.CENTER); yPos += 2 * Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else if (downleft) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); } else if (upcenter) { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - 1) / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Actor.java0000644000175000017500000001243612533641120025347 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.util.HashSet; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.command.OldResize; @SuppressWarnings("serial") public class Actor extends OldGridElement { private Vector getStringVector() { Vector ret = Utils.decomposeStrings(getPanelAttributes()); return ret; } @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); g2.setColor(fgColor); boolean ADAPT_SIZE = false; Vector tmp = getStringVector(); int yPos = 6 * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.drawLine(getRectangle().width / 2 - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 4, yPos, getRectangle().width / 2 + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 4, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); TextLayout l = new TextLayout(s, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Rectangle2D r2d = l.getBounds(); int width = (int) r2d.getWidth(); int xPos = getRectangle().width / 2 - width / 2; if (xPos < 0) { ADAPT_SIZE = true; break; } Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width * 0.5, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } if (ADAPT_SIZE) { new OldResize(this, -Main.getHandlerForElement(this).getGridSize(), 0, 0, 0).execute(Main.getHandlerForElement(this)); new OldResize(this, 0, 0, Main.getHandlerForElement(this).getGridSize(), 0).execute(Main.getHandlerForElement(this)); return; } if (yPos > getRectangle().height) { new OldResize(this, 0, 0, 0, 20).execute(Main.getHandlerForElement(this)); return; } int startx = getRectangle().width / 2; g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillOval(startx - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawOval(startx - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); g2.drawLine(startx, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), startx, (int) ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2.5)); g2.drawLine(startx - 2 * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 1.3), startx + 2 * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 1.3)); // Feet g2.drawLine(startx, (int) ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2.5), startx - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 5); g2.drawLine(startx, (int) ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 2.5), startx + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 5); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int links = Main.getHandlerForElement(this).realignToGrid(false, x + width / 2 - (int) (25 * zoom)); int rechts = Main.getHandlerForElement(this).realignToGrid(false, x + width / 2 + (int) (35 * zoom)); int oben = Main.getHandlerForElement(this).realignToGrid(false, y); int unten = Main.getHandlerForElement(this).realignToGrid(false, y + (int) (75 * zoom)); StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(links, oben); p.addPoint(rechts, oben); p.addPoint(rechts, unten); p.addPoint(links, unten, true); return p; } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/ThreeWayRelation.java0000644000175000017500000000424212533641120027521 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class ThreeWayRelation extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); Polygon poly = new Polygon(); poly.addPoint(getRectangle().width / 2, 0); poly.addPoint(getRectangle().width, getRectangle().height / 2); poly.addPoint(getRectangle().width / 2, getRectangle().height - 1); poly.addPoint(0, getRectangle().height / 2); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawPolygon(poly); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); y += 1; width += 1; p.addPoint(x + width / 2, y); p.addPoint(x + width, y + height / 2); p.addPoint(x + width / 2, y + height); p.addPoint(x, y + height / 2, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Package.java0000644000175000017500000002170612533641120025632 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Area; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Package extends OldGridElement { Area lastKnown = new Area(); private Vector getStringVector() { Vector ret = Utils.decomposeStrings(getPanelAttributes()); return ret; } @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); Vector tmp = new Vector(getStringVector()); // in order to make the addition of "--" possible if (tmp.size() == 0) { tmp.add(" "); } if (!tmp.contains("--")) { tmp.add("--"); } int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); boolean borders = false; // G. Mueller start boolean normal = false; // int maxUpperBox=5*this.getHandler().getFontHandler().getFontsize(); int maxUpperBox = (int) (getRectangle().width * 0.4); // I think this looks better int lines = 0; int yPosBorder = yPos; // LME: coloring (some code doubled) for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (tmp.elementAt(0).equals("--") && !borders) { yPosBorder = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); // if there is no Packagename } if (s.equals("--") && !borders) { g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, maxUpperBox, yPosBorder); g2.fillRect(0, yPosBorder, getRectangle().width - 1, getRectangle().height - yPosBorder - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, maxUpperBox, yPosBorder); g2.drawRect(0, yPosBorder, getRectangle().width - 1, getRectangle().height - yPosBorder - 1); // yPos to write the String centered yPosBorder = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2 + yPosBorder / 2 + getRectangle().height / 2 - (tmp.size() - lines) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; } else if (!normal && i > 1 && tmp.elementAt(i - 1).equals("--") && tmp.elementAt(i).startsWith("left:")) { yPosBorder = (lines + 1) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2 + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); } else if (!borders) { maxUpperBox = (int) Math.max(maxUpperBox, Main.getHandlerForElement(this).getFontHandler().getTextWidth(s) + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); yPosBorder += (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); } else if (normal) { yPosBorder += (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); } else if (!normal) { yPosBorder += (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); } } for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (tmp.elementAt(0).equals("--") && !borders) { yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); // if there is no Packagename } if (s.equals("--") && !borders) { borders = true; // g2.drawRect(0,0,maxUpperBox,yPos); // g2.drawRect(0,yPos,this.getWidth()-1,this.getHeight()-yPos-1); // yPos to write the String centered yPos = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2 + yPos / 2 + getRectangle().height / 2 - (tmp.size() - lines) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; } else if (!normal && i > 1 && tmp.elementAt(i - 1).equals("--") && tmp.elementAt(i).startsWith("left:")) { // writes the string normal yPos = (lines + 1) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s.substring(5), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); normal = true; } else if (!borders) { lines++; maxUpperBox = (int) Math.max(maxUpperBox, Main.getHandlerForElement(this).getFontHandler().getTextWidth(s) + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else if (normal) { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else if (!normal) { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // G. Mueller End } /* Rectangle r=this.getBounds(); g.drawRect(0,0,(int)r.getWidth()-1,(int)r.getHeight()-1); if (_selected) { g.drawRect(1,1,(int)r.getWidth()-3,(int)r.getHeight()-3); } */ } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); Vector tmp = new Vector(getStringVector()); if (tmp.size() == 0) { tmp.add(" "); } int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); boolean borders = false; // int maxUpperBox=5*this.getHandler().getFontHandler().getFontsize(); int maxUpperBox = (int) (width * 0.4); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); // G. Mueller start if (tmp.elementAt(0).equals("--") && !borders) { yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); // if there is no Packagename } // G.Mueller End if (s.equals("--") && !borders) { borders = true; } else if (!borders) { maxUpperBox = (int) Math.max(maxUpperBox, Main.getHandlerForElement(this).getFontHandler().getTextWidth(s) + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); yPos += (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); } } p.addPoint(x, y); p.addPoint(x + maxUpperBox, y); p.addPoint(x + maxUpperBox, y + yPos); p.addPoint(x + width, y + yPos); p.addPoint(x + width, y + height); p.addPoint(x, y + height, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SynchBarHorizontal.java0000644000175000017500000000713312533641120030060 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.command.OldResize; @SuppressWarnings("serial") public class SynchBarHorizontal extends OldGridElement { private int textWidth = 0; @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); textWidth = 0; // reset Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; boolean ADAPT_SIZE_X = false; int textHeight = tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); TextLayout l = new TextLayout(s, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Rectangle2D r2d = l.getBounds(); textWidth = (int) r2d.getWidth() > textWidth ? (int) r2d.getWidth() : textWidth; if (getRectangle().width - textWidth < 0) { ADAPT_SIZE_X = true; break; } yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, 0, yPos, AlignHorizontal.LEFT); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } if (ADAPT_SIZE_X) { new OldResize(this, -Main.getHandlerForElement(this).getGridSize(), 0, 0, 0).execute(Main.getHandlerForElement(this)); new OldResize(this, 0, 0, Main.getHandlerForElement(this).getGridSize(), 0).execute(Main.getHandlerForElement(this)); return; } if (textHeight > getRectangle().height) { new OldResize(this, 0, 0, 0, 20).execute(Main.getHandlerForElement(this)); return; } g2.fillRect(textWidth + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), getRectangle().height / 2 - (int) (3 * zoom), getRectangle().width - textWidth - (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2, (int) (5 * zoom)); } /* public int doesCoordinateAppearToBeConnectedToMe(Point p) { int ret=0; int tmpX=p.x-this.getX(); int tmpY=p.y-this.getY(); if (tmpX>(textWidth+4) && tmpX0 && tmpY<8) ret+=1; if (tmpY>this.getHeight()/2-8 && tmpY getResizeArea(int x, int y) { Set returnSet = super.getResizeArea(x, y); returnSet.remove(Direction.UP); returnSet.remove(Direction.DOWN); return returnSet; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SynchBarVertical.java0000644000175000017500000000706012533641120027477 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.command.OldResize; @SuppressWarnings("serial") public class SynchBarVertical extends OldGridElement { private int textHeight = 0; @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); int yPos = 0; textHeight = 0; // reset Vector tmp = Utils.decomposeStrings(getPanelAttributes()); textHeight = tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); boolean ADAPT_SIZE = false; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); TextLayout l = new TextLayout(s, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Rectangle2D r2d = l.getBounds(); int width = (int) r2d.getWidth(); if (getRectangle().width / 2 - width / 2 < 0) { ADAPT_SIZE = true; break; } Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } if (ADAPT_SIZE) { new OldResize(this, -Main.getHandlerForElement(this).getGridSize(), 0, 0, 0).execute(Main.getHandlerForElement(this)); new OldResize(this, 0, 0, Main.getHandlerForElement(this).getGridSize(), 0).execute(Main.getHandlerForElement(this)); return; } if (yPos > getRectangle().height) { new OldResize(this, 0, 0, 0, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts())).execute(Main.getHandlerForElement(this)); return; } g2.fillRect(getRectangle().width / 2 - (int) (3 * zoom), textHeight + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), (int) (5 * zoom), getRectangle().height - textHeight - (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2); } /* public int doesCoordinateAppearToBeConnectedToMe(Point p) { int ret=0; int tmpX=p.x-this.getX(); int tmpY=p.y-this.getY(); if (tmpY>textHeight+4 && tmpY0 && tmpX<16) ret+=8; if (tmpX>this.getWidth()/2-4 && tmpX getResizeArea(int x, int y) { Set directions = super.getResizeArea(x, y); directions.remove(Direction.LEFT); // allow height changes only directions.remove(Direction.RIGHT); return directions; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Class.java0000644000175000017500000002621712533641120025346 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Class extends OldGridElement { // A.Mueller start private final Vector innerClasses = new Vector(); private boolean _isTemplate = false; private boolean _isInnerClass = false; private String _panelString = ""; private int _templateHeight = 0; private int _templateWidth = 0; // A.Mueller end private Vector getStringVector() { if (isInnerClass()) { return Utils.decomposeStrings(_panelString); // A.Mueller } Vector ret = Utils.decomposeStrings(getPanelAttributes()); return ret; } // A.Mueller start public Vector getInnerClasses() { return innerClasses; } public boolean isInnerClass() { return _isInnerClass; } public void setIsInnerClass(boolean i) { _isInnerClass = i; } public void setPanelString(String p) { _panelString = p; } // A.Mueller end @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); // setAutoresize(50, 50); int innerSoFar = 0; // A.Mueller _isTemplate = false; Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Vector tmp = getStringVector(); int yPos = 0; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); Composite[] composites = colorize(g2); // LME: enable colors g2.setColor(fgColor); Rectangle r = getRectangle(); LineType lineType = LineType.SOLID; int thickness = 1; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("bt=.")) { lineType = LineType.DASHED; } if (s.equals("bt=*")) { thickness = 2; } else if (s.startsWith("template") && i == 0) { String[] template = s.split("="); if (template.length != 2) { _isTemplate = false; } else { _isTemplate = true; } } } if (!_isTemplate) { g2.setComposite(composites[1]); // set aplha composite for drawing the background color g2.setColor(bgColor); g2.fillRect(0, 0, r.getWidth() - 1, r.getHeight() - 1); g2.setComposite(composites[0]); // reset composite settings if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.setStroke(Utils.getStroke(lineType, thickness)); g2.drawRect(0, 0, r.getWidth() - 1, r.getHeight() - 1); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } boolean CENTER = true; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("bt=.") || s.equals("bt=*")) { /* don't draw these lines because they are only for markup */ } else if (s.equals("--")) { CENTER = false; // A.Mueller start if (_isTemplate) { g2.drawLine(0, yPos, getRectangle().width - 1 - getRectangle().width / 10, yPos); } else { g2.drawLine(0, yPos, getRectangle().width - 1, yPos); // A.Mueller end } yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); // A.Mueller start } else if (s.equals("{active}") && i == 0) { g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, getRectangle().height - 1); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, getRectangle().height - 1); yPos = getRectangle().height / 2 - (tmp.size() - 1) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; } else if (s.startsWith("template") && i == 0) { String[] template = s.split("="); if (template.length == 2) { _templateWidth = (int) (Main.getHandlerForElement(this).getFontHandler().getTextWidth(template[1]) + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); _templateHeight = (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); Polygon border = new Polygon(); border.addPoint(0, _templateHeight / 2); border.addPoint(getRectangle().width - _templateWidth, _templateHeight / 2); border.addPoint(0, _templateHeight / 2); border.addPoint(0, getRectangle().height); border.addPoint(0, getRectangle().height - 1); border.addPoint(getRectangle().width - getRectangle().width / 10, getRectangle().height - 1); border.addPoint(getRectangle().width - getRectangle().width / 10, getRectangle().height - 1); border.addPoint(getRectangle().width - getRectangle().width / 10, _templateHeight + 1); border.addPoint(getRectangle().width - _templateWidth, _templateHeight + 1); border.addPoint(getRectangle().width - _templateWidth, _templateHeight / 2); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); g2.setComposite(composites[1]); // set alpha composite g2.setColor(bgColor); g2.fillRect(getRectangle().width - _templateWidth, 0, _templateWidth, _templateHeight + 1); g2.fillPolygon(border); g2.setComposite(composites[0]); // reset composite if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } // draw border lines of template box g2.drawRect(getRectangle().width - _templateWidth, 0, _templateWidth - 1, _templateHeight); // template box Main.getHandlerForElement(this).getFontHandler().writeText(g2, template[1], getRectangle().width - _templateWidth + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), AlignHorizontal.LEFT); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); // draw border lines of class g2.drawLine(0, _templateHeight / 2, getRectangle().width - _templateWidth, _templateHeight / 2); g2.drawLine(0, _templateHeight / 2, 0, getRectangle().height); g2.drawLine(0, getRectangle().height - 1, getRectangle().width - getRectangle().width / 10, getRectangle().height - 1); g2.drawLine(getRectangle().width - getRectangle().width / 10, getRectangle().height - 1, getRectangle().width - getRectangle().width / 10, _templateHeight); yPos = yPos + _templateHeight + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { _isTemplate = false; } } else if (s.equals("{innerclass")) { StringBuilder sb = new StringBuilder(""); // Counting the inner lines helps to determine the Height of the // resulting innerClass (lines times the fontsize gives us the height of // the contents) by adding also the INNER words we make sure to have enough // space at the bottom since the lines of the classes also need space int innerLines = 0; int innerCount = 0; for (i++; i < tmp.size(); i++) { if (tmp.elementAt(i).equals("{innerclass")) { innerCount++; innerLines++; } else if (tmp.elementAt(i).equals("innerclass}")) { if (innerCount > 0) { innerCount--; } else { break; } } else { innerLines++; } sb.append("\n").append(tmp.elementAt(i)); } String state = sb.toString(); Class temp; try { temp = innerClasses.get(innerSoFar); temp.setPanelString(state); } catch (ArrayIndexOutOfBoundsException e) { temp = new Class(); innerClasses.add(innerSoFar, temp); Main.getHandlerForElement(this).setHandlerAndInitListeners(temp); temp.setIsInnerClass(true); temp.setPanelString(state); innerSoFar++; } int height = innerLines * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * --innerLines; temp.setLocation(5, yPos); if (_isTemplate) { temp.setSize((int) (getRectangle().width - getRectangle().width / 10 - 10 * zoom), height); } else { temp.setSize((int) (getRectangle().width - 10 * zoom), height); } temp.paintEntity(g.create((int) (5 * zoom), yPos, (int) (getRectangle().width - 5 * zoom), temp.getRectangle().height)); yPos = yPos + temp.getRectangle().height + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); // A.Mueller end } else { if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER) { // A.Mueller if (_isTemplate) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - getRectangle().width / 10.0) / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); } } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } // g2.setStroke(Constants.getStroke(0, 1)); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { // LME: define the polygon on which relations stick on if (!_isTemplate) { return super.generateStickingBorder(x, y, width, height); } StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(x, y + _templateHeight / 2); p.addPoint(x + 9 * width / 10 + 1, y + _templateHeight / 2); p.addPoint(x + 9 * width / 10 + 1, y + height); p.addPoint(x, y + height, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/ActiveClass.java0000644000175000017500000000370112533641120026473 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class ActiveClass extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(fgColor); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = 0; yPos = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } g2.drawLine(0, 0, getRectangle().width, 0); g2.drawLine(getRectangle().width - 1, 0, getRectangle().width - 1, getRectangle().height - 1); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(0, getRectangle().height - 1, 0, 0); g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, getRectangle().height - 1); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, 0, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, getRectangle().height - 1); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Socket.java0000644000175000017500000000223212533641120025520 0ustar benbenpackage com.baselet.element.old.element; // Some import to have access to more Java features import java.awt.Graphics; import java.awt.Graphics2D; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Socket extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(fgColor); int fnt = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2; this.setSize(fnt + 2, fnt + 2); int h = getRectangle().height; g2.drawArc(0, 0, h - 1, h - 1, 90, 180); g2.drawOval((int) (4 * zoom), (int) (4 * zoom), h - (int) (9 * zoom), h - (int) (9 * zoom)); } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SeqObjectActive.java0000644000175000017500000000224012533641120027302 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class SeqObjectActive extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); } @Override public Set getResizeArea(int x, int y) { Set returnSet = super.getResizeArea(x, y); returnSet.remove(Direction.LEFT); returnSet.remove(Direction.RIGHT); return returnSet; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/TemplateClass.java0000644000175000017500000000372512533641120027041 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class TemplateClass extends OldGridElement { public TemplateClass() { super(); } private Vector getStringVector() { return Utils.decomposeStrings(getPanelAttributes()); } @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(fgColor); // Constants.getFRC(g2); Vector tmp = getStringVector(); int yPos = 0; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); boolean CENTER = true; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { CENTER = false; g2.drawLine(0, yPos, getRectangle().width, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } Rectangle r = getRectangle(); g.drawRect(0, 0, r.getWidth() - 1, r.getHeight() - 1); /* if (_selected) { g.drawRect(1,1,(int)r.getWidth()-3,(int)r.getHeight()-3); } */ } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/ReceiveSignal.java0000644000175000017500000000463712533641120027023 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class ReceiveSignal extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); Polygon poly = new Polygon(); poly.addPoint(0, 0); poly.addPoint(getRectangle().width - 1, 0); poly.addPoint(getRectangle().width - 1, getRectangle().height - 1); poly.addPoint(0, getRectangle().height - 1); poly.addPoint((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() - 2, getRectangle().height / 2); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawPolygon(poly); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(x, y); p.addPoint(x + width, y); p.addPoint(x + width, y + height); p.addPoint(x, y + height); p.addPoint(x + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() - 2, y + height / 2, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Signal.java0000644000175000017500000001012212533641120025502 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class Signal extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(Color.red); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = 0; yPos = getRectangle().height / 2 - (tmp.size() - 1) * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; int signalType = 0; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals(">")) { signalType = 1; // send signal } else if (s.equals("<")) { signalType = 2; // accept signal } else if (s.equals("x")) { signalType = 3; // time signal } else { // draw string yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } if (signalType == 1) { // send signal g2.drawLine(0, 0, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, getRectangle().width - 1, getRectangle().height / 2); g2.drawLine(getRectangle().width, getRectangle().height / 2, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), getRectangle().height); g2.drawLine(0, getRectangle().height - 1, 0, 0); } else if (signalType == 2) { // accept signal g2.drawLine(0, 0, getRectangle().width, 0); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(0, 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() - 2, getRectangle().height / 2); g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() - 2, getRectangle().height / 2, 0, getRectangle().height); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, getRectangle().width - 1, 0); } else if (signalType == 3) { // time signal g2.drawLine(0, 0, getRectangle().width, 0); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.drawLine(getRectangle().width - 1, 0, 0, getRectangle().height - 1); } else { // NO signal specified g2.drawLine(0, 0, getRectangle().width, 0); g2.drawLine(getRectangle().width - 1, getRectangle().height - 1, 0, getRectangle().height - 1); g2.drawLine(getRectangle().width - 1, 0, getRectangle().width - 1, getRectangle().height - 1); g2.drawLine(0, getRectangle().height - 1, 0, 0); } } public int doesCoordinateAppearToBeConnectedToMe(Point p) { int ret = 0; int tmpX = p.x - getRectangle().x; int tmpY = p.y - getRectangle().y; if (tmpX > -4 && tmpX < getRectangle().width + 4) { if (tmpY > -4 && tmpY < 4) { ret += 1; } if (tmpY > getRectangle().height - 4 && tmpY < getRectangle().height + 4) { ret += 4; } } if (tmpY > -4 && tmpY < getRectangle().height + 4) { if (tmpX > -4 && tmpX < 12) { ret += 8; } if (tmpX > getRectangle().width - 4 && tmpX < getRectangle().width + 4) { ret += 2; } } return ret; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SeqDestroyMark.java0000644000175000017500000000230712533641120027210 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.HashSet; import java.util.Set; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class SeqDestroyMark extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; colorize(g2); // enable colors g2.setColor(fgColor); Rectangle r = getRectangle(); g2.drawLine(0, 0, r.getWidth() - 1, r.getHeight() - 1); g2.drawLine(r.getWidth() - 1, 0, 0, r.getHeight() - 1); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); int px = x + width / 2; int py = y + height / 2; p.addPoint(px - 4, py - 4); p.addPoint(px + 4, py - 4); p.addPoint(px + 4, py + 4); p.addPoint(px - 4, py + 4, true); return p; } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/InitialFinalState.java0000644000175000017500000000225712533641120027643 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class InitialFinalState extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(Color.red); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); boolean initialState = false; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("i")) { initialState = true; } } if (!initialState) { g2.drawOval(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.fillOval((int) (4 * zoom), (int) (4 * zoom), getRectangle().width - (int) (8 * zoom), getRectangle().height - (int) (8 * zoom)); } else { g2.fillOval(0, 0, getRectangle().width, getRectangle().height); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/State.java0000644000175000017500000000614512533641120025357 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class State extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRoundRect(0, 0, getRectangle().width - 1, getRectangle().height - 1, (int) (30 * zoom), (int) (30 * zoom)); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRoundRect(0, 0, getRectangle().width - 1, getRectangle().height - 1, (int) (30 * zoom), (int) (30 * zoom)); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = 0; // A.Mueller start if (tmp.contains("--") || tmp.contains("-.")) { yPos = 2 * (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { // A.Mueller end yPos = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; } boolean CENTER = true; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); // A.Mueller start if (s.equals("--")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.drawLine(0, yPos, getRectangle().width, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); CENTER = false; } else if (s.equals("-.")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); g2.drawLine(0, yPos, getRectangle().width, yPos); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); CENTER = false; } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (CENTER) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // A.Mueller end } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Decision.java0000644000175000017500000000336012533641120026030 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Decision extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); Polygon poly = new Polygon(); poly.addPoint(getRectangle().width / 2, 0); poly.addPoint(getRectangle().width, getRectangle().height / 2); poly.addPoint(getRectangle().width / 2, getRectangle().height); poly.addPoint(0, getRectangle().height / 2); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillPolygon(poly); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawPolygon(poly); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); y += 1; width += 1; p.addPoint(x + width / 2, y); p.addPoint(x + width, y + height / 2); p.addPoint(x + width / 2, y + height); p.addPoint(x, y + height / 2, true); return p; } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/HistoryState.java0000644000175000017500000000320312533641120026731 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; import java.util.HashSet; import java.util.Set; import com.baselet.control.Main; import com.baselet.control.enums.Direction; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class HistoryState extends OldGridElement { @Override public void paintEntity(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); g2.fillOval(0, 0, getRectangle().width, getRectangle().height); // Measure the font and the message Rectangle2D bounds = Main.getHandlerForElement(this).getFontHandler().getFont().getStringBounds("H", g2.getFontRenderContext()); LineMetrics metrics = Main.getHandlerForElement(this).getFontHandler().getFont().getLineMetrics("H", g2.getFontRenderContext()); float width = (float) bounds.getWidth(); // The width of our text float lineheight = metrics.getHeight(); // Total line height float ascent = metrics.getAscent(); // Top of text to baseline // Now display the message centered horizontally and vertically in this float x0 = (getRectangle().width - width) / 2; float y0 = (getRectangle().height - lineheight) / 2 + ascent; g2.setColor(Color.WHITE); g2.drawString("H", x0, y0); g2.setColor(fgColor); } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Node.java0000644000175000017500000000740312533641120025162 0ustar benbenpackage com.baselet.element.old.element; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Polygon; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class Node extends OldGridElement { public Node() { super(); } @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); int size_3d = (int) (10 * zoom); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, size_3d, getRectangle().width - size_3d - 1, getRectangle().height - size_3d - 1); Polygon p = new Polygon(); p.addPoint(getRectangle().width - size_3d - 1, getRectangle().height - 1); p.addPoint(getRectangle().width - size_3d - 1, size_3d); p.addPoint(getRectangle().width - 1, 0); p.addPoint(getRectangle().width - 1, getRectangle().height - size_3d - 1); Polygon p1 = new Polygon(); p1.addPoint(0, size_3d); p1.addPoint(size_3d, 0); p1.addPoint(getRectangle().width - 1, 0); p1.addPoint(getRectangle().width - size_3d - 1, size_3d); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); g2.setColor(new Color(230, 230, 230)); g2.fillPolygon(p); g2.fillPolygon(p1); g2.setComposite(composites[0]); g2.setColor(fgColor); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, size_3d, getRectangle().width - size_3d - 1, getRectangle().height - size_3d - 1); // draw polygons by hand to avoid double painted line g2.drawLine(0, size_3d, size_3d, 0); g2.drawLine(size_3d, 0, getRectangle().width - 1, 0); g2.drawLine(getRectangle().width - 1, 0, getRectangle().width - 1, getRectangle().height - size_3d - 1); g2.drawLine(getRectangle().width - 1, getRectangle().height - size_3d - 1, getRectangle().width - size_3d - 1, getRectangle().height - 1); g2.drawLine(getRectangle().width - size_3d - 1, size_3d, getRectangle().width - 1, 0); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); yPos = yPos + size_3d; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (s.startsWith("center:")) { s = s.substring(7); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (getRectangle().width - size_3d - 1) / 2.0, yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2.0, yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { int size_3d = 10; StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(x, y + size_3d); p.addPoint(x, y + height); p.addPoint(x + width - size_3d, y + height); p.addPoint(x + width, y + height - size_3d); p.addPoint(x + width, y); p.addPoint(x + size_3d, y, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/InteractionFrame.java0000644000175000017500000001133512533641120027526 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class InteractionFrame extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); float yPos = 0; yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.setComposite(composites[1]); g2.setColor(bgColor); g2.fillRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int textWidth = 0; // A.Mueller start boolean center = false; int topHeight = tmp.size(); int maxWidthTemp = 0; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); maxWidthTemp = (int) Math.max(Main.getHandlerForElement(this).getFontHandler().getTextWidth(s), maxWidthTemp); if (s.equals("--")) { textWidth = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + maxWidthTemp + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); topHeight = i; yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); center = true; } else if (s.equals("-.")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); g2.drawLine(0, (int) yPos, getRectangle().width, (int) yPos); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += Main.getHandlerForElement(this).getFontHandler().getFontSize(); if (center) { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, (int) yPos, AlignHorizontal.CENTER); } else { Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2), (int) yPos, AlignHorizontal.LEFT); } yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } if (textWidth == 0) { textWidth = maxWidthTemp; /* for (int i=0; itextWidth)?((int)r2d.getWidth()):(textWidth); } */ // A.Mueller end } int w = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 7 > textWidth ? (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 7 : textWidth; // A.Mueller start int h = topHeight * ((int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) (3 * zoom)) + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); int sw = w - (topHeight - 1) * (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); // // int h=tmp.size()*(this.getHandler().getFontHandler().getFontsize()+3)+this.getHandler().getFontHandler().getFontsize(); // int sw=w-(tmp.size()-1)*this.getHandler().getFontHandler().getFontsize(); // // A.Mueller end g2.drawLine(0, h, sw, h); g2.drawLine(w + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, w + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); g2.drawLine(sw, h, w + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/ErrorOccurred.java0000644000175000017500000000336112533641120027054 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.enums.AlignHorizontal; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class ErrorOccurred extends OldGridElement { private final String errorMessage; public ErrorOccurred() { errorMessage = "This Element has an Error!"; } public ErrorOccurred(String errorMessage) { super(); this.errorMessage = errorMessage; } @Override public void paintEntity(Graphics g) { DiagramHandler handlerForElement = Main.getHandlerForElement(this); Graphics2D g2 = (Graphics2D) g; g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); if (handlerForElement.getDrawPanel().getSelector().isSelected(this)) { g2.setColor(Converter.convert(ColorOwn.SELECTION_FG)); } else { g2.setColor(Color.red); } g2.setFont(handlerForElement.getFontHandler().getFont()); handlerForElement.getFontHandler().writeText(g2, errorMessage, 0, 20, AlignHorizontal.LEFT); g2.setColor(fgColor); } @Override public GridElement cloneFromMe() { try { GridElement ge = new ErrorOccurred(errorMessage); ge.setPanelAttributes(getPanelAttributes()); // copy states ge.setRectangle(getRectangle()); Main.getHandlerForElement(this).setHandlerAndInitListeners(ge); return ge; } catch (Exception e) { log.error("Error at calling CloneFromMe() on entity", e); } return null; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SynchBar.java0000644000175000017500000000360412533641120026005 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class SynchBar extends OldGridElement { @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(Color.red); int yPos = 0; yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); Vector tmp = Utils.decomposeStrings(getPanelAttributes()); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, 0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // g2.fillRect(0,7,this.getWidth(),this.getHeight()-15); g2.fillRect(0, (int) (7 * zoom), getRectangle().width, (int) (5 * zoom)); } public int doesCoordinateAppearToBeConnectedToMe(Point p) { int ret = 0; int tmpX = p.x - getRectangle().x; int tmpY = p.y - getRectangle().y; if (tmpX > -4 && tmpX < getRectangle().width + 4) { if (tmpY > 0 && tmpY < 8) { ret += 1; } if (tmpY > getRectangle().height - 16 && tmpY < getRectangle().height + 0) { ret += 4; } } // if (tmpY>-4 && tmpY0 && tmpX<8) ret+=8; // if (tmpX>this.getWidth()-4 && tmpX tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = getRectangle().height / 2 - tmp.size() * (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()) / 2; for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // g2.drawLine(0,0,this.getWidth()-this.getHandler().getFontHandler().getFontsize(),0); // g2.drawLine(this.getWidth()-this.getHandler().getFontHandler().getFontsize(), this.getHeight()-1, 0, this.getHeight()-1); // g2.drawLine(this.getWidth()-this.getHandler().getFontHandler().getFontsize(),0,this.getWidth()-1,this.getHeight()/2); // g2.drawLine(this.getWidth(),this.getHeight()/2,this.getWidth()-this.getHandler().getFontHandler().getFontsize(),this.getHeight()); // g2.drawLine(0, this.getHeight()-1, 0, 0); } @Override public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(0, 0); p.addPoint(x, y); p.addPoint(x + width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), y); p.addPoint(x + width, y + height / 2); p.addPoint(x + width - (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), y + height); p.addPoint(x, y + height, true); return p; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/Interface.java0000644000175000017500000001126012533641120026171 0ustar benbenpackage com.baselet.element.old.element; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.util.HashSet; import java.util.Set; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.command.OldResize; @SuppressWarnings("serial") public class Interface extends OldGridElement { private Vector getStringVector() { return Utils.decomposeStrings(getPanelAttributes()); } @Override public void paintEntity(Graphics g) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); Composite[] composites = colorize(g2); // enable colors g2.setColor(fgColor); /* FontRenderContext rendering; if (Constants.getFontsize()>12) { rendering=new FontRenderContext(null, true, true); g2.setRenderingHints(Constants.UxRenderingQualityHigh()); } else { rendering=new FontRenderContext(null, false, false); g2.setRenderingHints(Constants.UxRenderingQualityLow()); } */ boolean ADAPT_SIZE = false; Vector tmp = getStringVector(); int yPos = 0; yPos += 2 * Main.getHandlerForElement(this).getGridSize(); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); if (s.equals("--")) { yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); g2.drawLine(0, yPos, getRectangle().width, yPos); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } else { yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); TextLayout l = new TextLayout(s, Main.getHandlerForElement(this).getFontHandler().getFont(), g2.getFontRenderContext()); Rectangle2D r2d = l.getBounds(); int width = (int) r2d.getWidth(); int xPos = getRectangle().width / 2 - width / 2; if (xPos < 0) { ADAPT_SIZE = true; break; } Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, getRectangle().width / 2.0, yPos, AlignHorizontal.CENTER); yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } } if (ADAPT_SIZE) { new OldResize(this, -Main.getHandlerForElement(this).getGridSize(), 0, 0, 0).execute(Main.getHandlerForElement(this)); new OldResize(this, 0, 0, Main.getHandlerForElement(this).getGridSize(), 0).execute(Main.getHandlerForElement(this)); return; } if (yPos > getRectangle().height) { new OldResize(this, 0, 0, 0, 20).execute(Main.getHandlerForElement(this)); return; } g2.setComposite(composites[1]); g2.setColor(bgColor); g.fillOval(getRectangle().width / 2 - (int) (10 * zoom), 0, (int) (20 * zoom), (int) (20 * zoom)); g2.setComposite(composites[0]); if (Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { g2.setColor(fgColor); } else { g2.setColor(fgColorBase); } g.drawOval(getRectangle().width / 2 - (int) (10 * zoom), 0, (int) (20 * zoom), (int) (20 * zoom)); /* if (_selected) { g.drawOval(this.getWidth()/2-Constants.getFontsize()+1, 1, 2*Constants.getFontsize()-2, 2*Constants.getFontsize()-2); } */ } /* public int doesCoordinateAppearToBeConnectedToMe(Point p) { int tmpX=p.x-this.getX(); int tmpY=p.y-this.getY(); int links=this.getWidth()/2-this.getHandler().getMainUnit(); int rechts=this.getWidth()/2+this.getHandler().getMainUnit(); int oben=0; int unten=2*this.getHandler().getMainUnit(); if (tmpX>links-4 && tmpXoben-4 && tmpYunten-4 && tmpYoben-4 && tmpYlinks-4 && tmpXrechts-4 && tmpX getResizeArea(int x, int y) { return new HashSet(); // deny size changes } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/element/SimpleComponent.java0000644000175000017500000000643612533641120027416 0ustar benbenpackage com.baselet.element.old.element; // Some import to have access to more Java features import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.element.old.OldGridElement; @SuppressWarnings("serial") public class SimpleComponent extends OldGridElement { // Change this method if you want to edit the graphical // representation of your custom element. @Override public void paintEntity(Graphics g) { // Some unimportant initialization stuff; setting color, font // quality, etc. You should not have to change this. Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); colorize(g2); // enable colors g2.setColor(fgColor); // It's getting interesting here: // First, the strings you type in the element editor are read and // split into lines. // Then, by default, they are printed out on the element, aligned // to the left. // Change this to modify this default text printing and to react // to special strings // (like the "--" string in the UML class elements which draw a line). Vector tmp = Utils.decomposeStrings(getPanelAttributes()); int yPos = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); for (int i = 0; i < tmp.size(); i++) { String s = tmp.elementAt(i); yPos += (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); Main.getHandlerForElement(this).getFontHandler().writeText(g2, s, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() * 3, yPos, AlignHorizontal.LEFT); // offset into box yPos += Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(); } // Finally, change other graphical attributes using // drawLine, getWidth, getHeight.. int fnt = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, getRectangle().width - 1, 0); // top g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), getRectangle().height - 1, getRectangle().width - 1, getRectangle().height - 1); // bottom // left side g2.drawLine((int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), 0, (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(), fnt); // top g2.drawLine(fnt, fnt * 2, fnt, fnt * 3); // middle g2.drawLine(fnt, fnt * 4, fnt, getRectangle().height - 1); // bottom g2.drawLine(getRectangle().width - 1, 0, getRectangle().width - 1, getRectangle().height - 1); // right side g2.drawLine(0, fnt, fnt * 2, fnt); // top box top line g2.drawLine(0, fnt * 2, fnt * 2, fnt * 2); // top box bottom line g2.drawLine(0, fnt, 0, fnt * 2); // top box left line g2.drawLine(fnt * 2, fnt, fnt * 2, fnt * 2); // top box right line g2.drawLine(0, fnt * 3, fnt * 2, fnt * 3); // bottom box top line g2.drawLine(0, fnt * 4, fnt * 2, fnt * 4); // bottom box bottom line g2.drawLine(0, fnt * 3, 0, fnt * 4); // bottom box left line g2.drawLine(fnt * 2, fnt * 3, fnt * 2, fnt * 4); // bottom box right line } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/allinone/0000755000175000017500000000000012533641120023576 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/allinone/SequenceDiagram.java0000644000175000017500000007450212533641120027506 0ustar benbenpackage com.baselet.element.old.allinone; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.awt.font.TextLayout; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.sourceforge.jlibeps.epsgraphics.EpsGraphics2D; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.enums.FormatLabels; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.diagram.FontHandler; import com.baselet.element.interfaces.GridElementDeprecatedAddons; import com.baselet.element.old.OldGridElement; // An interaction represents a synchronous/asynchronous message // that is sent between two objects. class Interaction { private final int srcObj; private final boolean srcObjHasControl; private final int arrowKind; // 1=SYNC, 2= ASYNC, 3=EDGE, 4=FILLED private final int lineKind; // 1=SOLID, 2=DOTTED private final int destObj; private final boolean destObjHasControl; private final String methodName; public Interaction(int srcObj, boolean srcObjHasControl, int arrowKind, int lineKind, int destObj, boolean destObjHasControl, String methodName) { this.srcObj = srcObj; this.srcObjHasControl = srcObjHasControl; this.arrowKind = arrowKind; this.lineKind = lineKind; this.destObj = destObj; this.destObjHasControl = destObjHasControl; this.methodName = methodName; } public boolean hasControl(int objNum) { return srcObjHasControl && srcObj == objNum || destObjHasControl && destObj == objNum; } @Override public boolean equals(Object o) { if (!(o instanceof Interaction)) { return false; } Interaction i = (Interaction) o; return srcObj == i.srcObj && srcObjHasControl == i.srcObjHasControl && arrowKind == i.arrowKind && destObj == i.destObj && destObjHasControl == i.destObjHasControl && methodName == null || methodName.equals(i.methodName); } @Override public int hashCode() { return (methodName != null ? methodName.hashCode() : 1) + srcObj + (srcObjHasControl ? 1 : 0) + arrowKind + destObj + (destObjHasControl ? 1 : 0); } public int getSrcObj() { return srcObj; } public boolean getSrcObjHasControl() { return srcObjHasControl; } public int getArrowKind() { return arrowKind; } public int getLineKind() { return lineKind; } public int getDestObj() { return destObj; } public boolean getDestObjHasControl() { return destObjHasControl; } public String getMethodName() { return methodName; } } // Contains all interactions entered by the user and // offers various comfort-functions for finding and // working with interactions class InteractionManagement { private final Set[] level; // private Set[] level; @SuppressWarnings("unchecked") InteractionManagement(int numLevels) { level = new HashSet[numLevels]; for (int i = 0; i < numLevels; i++) { level[i] = new HashSet(); } } public boolean controlBoxExists(int levelNum, int objNum) { Iterator it = level[levelNum - 1].iterator(); while (it.hasNext()) { Interaction ia = it.next(); if (ia.hasControl(objNum)) { return true; } } return false; } public void add(int numLevel, Interaction i) { level[numLevel - 1].add(i); } public Set getInteractionsInLevel(int levelNum) { return level[levelNum - 1]; } public int getNumLevels() { return level.length; } } @SuppressWarnings("serial") public class SequenceDiagram extends OldGridElement { public int controlFlowBoxWidth = 20; // the dimensions for the rectangle(s) (=objects) in the first line public int rectDistance; // computed distance between two columns public int rectHeight; // computed public int rectWidth; // computed // int extraTextSpace = 0; public int borderDistance = 10; // d between the component bordeR and the diagram private int yOffsetforTitle = 0; public int rectToFirstLevelDistance = 0; public int levelHeight = 30;// LME//60; // these two constants are important for the arrowhead public int arrowX = 5; public int arrowY = 5; public static final int SYNC = 1; public static final int ASYNC = 2; public static final int EDGE = 3; // LME public static final int FILLED = 4; // LME public static final int SOLID = 1; // LME public static final int DOTTED = 2; // LME private Map labeltonumber; private int levelNum = 0; private InteractionManagement im; @Override public void paintEntity(Graphics g) { rectDistance = 60; zoomValues(); float zoom = Main.getHandlerForElement(this).getZoomFactor(); // Some unimportant initialization stuff; setting color, font // quality, etc. You should not have to change this. Graphics2D g2 = (Graphics2D) g; FontHandler fontHandler = Main.getHandlerForElement(this).getFontHandler(); g2.setFont(fontHandler.getFont()); g2.setColor(fgColor); // draw the border g2.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); levelNum = 1; Vector lines = Utils.decomposeStrings(getPanelAttributes()); if (lines.size() == 0) { return; } if (lines.elementAt(0).startsWith("title:")) { String title = lines.elementAt(0).substring("title:".length()); if (title != null && title.length() > 0) { fontHandler.writeText(g2, title, (int) (5 * zoom), (int) fontHandler.getFontSize() + (int) fontHandler.getDistanceBetweenTexts(), AlignHorizontal.LEFT); int titlewidth = (int) fontHandler.getTextWidth(title); int ty = (int) (8 * zoom) + (int) (fontHandler.getFontSize() + fontHandler.getDistanceBetweenTexts()); g2.drawLine(0, ty, titlewidth + (int) (10 * zoom), ty); g2.drawLine(titlewidth + (int) (10 * zoom), ty, titlewidth + ty + (int) (10 * zoom), 0); lines.remove(0); yOffsetforTitle = (int) (25 * zoom); } } else { yOffsetforTitle = 0; } for (int i = 1; i < lines.size(); i++) { String element = lines.elementAt(i); if (element.indexOf("iframe{") >= 0) { element = "9999->0:" + element; // dummy: space for interactionframe lines.set(i, element); } else if (element.indexOf("iframe}") >= 0) { element = "9999<-0:" + element; // dummy: space for interactionframe lines.set(i, element); } // AB: match whitespace characters from the beginning to the end of the line if (lines.elementAt(i).matches("\\A\\s*\\z")) { continue; } levelNum++; } if (lines.size() == 0) { return; // return if it only has the title line (Issue 146) } String firstLine = lines.elementAt(0); Vector obj = Utils.decomposeStrings(firstLine, "|"); int numObjects = obj.size(); // LABEL ADDING // get the labels of the Sequencediagram StringBuilder sb = new StringBuilder(""); // delete the ids from the header labeltonumber = new HashMap(); Pattern p_label = Pattern.compile("([^\\~]+)(\\~([a-zA-Z0-9]+))?(\\_)?"); for (int i = 1; i <= numObjects; i++) { Matcher m = p_label.matcher(obj.get(i - 1)); if (m.matches() && m.group(2) != null) { labeltonumber.put(m.group(3), i); sb.append("|").append(m.group(1)).append(m.group(4) == null ? "" : m.group(4)); } else { sb.append("|").append(obj.get(i - 1)); } if (!labeltonumber.containsKey(Integer.toString(i))) // only write number if no other label has this number { labeltonumber.put(Integer.toString(i), i); // columnnumber as label for backward compatibility } } String newhead = sb.toString(); obj = Utils.decomposeStrings(newhead.length() > 0 ? newhead.substring(1) : "", "|"); // LABELADDING STOP (exchanged parseInteger Methods with labeltonumber.get methods calcWidthOfLineHeaderBoxes(g2, fontHandler, obj, numObjects); // parse the messages int curLevel = 0; im = new InteractionManagement(levelNum); String boxStrings = ""; for (int i = 1; i < lines.size(); i++) { String methodName = ""; if (lines.elementAt(i).matches("\\A\\s*\\z")) { continue; } curLevel++; Vector interactions = Utils.decomposeStrings(lines.elementAt(i), ";"); for (int j = 0; j < interactions.size(); j++) { Pattern p = Pattern.compile("\\A(\\w+)(->>|->|-/>|.>>|.>|./>|->>>|.>>>|<<-|<-|>|->|-/>|.>>|.>|./>|->>>|.>>>)(\\d+)(:((\\d+)(,(\\d+))*))*(?::(.*))?\\z"); // 1->2:1,2:methodName // 1->2:abc Matcher m = p.matcher(interactions.elementAt(j)); if (!m.matches()) { continue; } Integer srcObj = labeltonumber.get(m.group(1)); Integer destObj = labeltonumber.get(m.group(3)); String methodNameFromText = m.group(9); if (srcObj != null && destObj != null && methodNameFromText != null) { Integer span = Math.abs(srcObj - destObj); if (span != 0) { double lineSpaceRequiredForMessage = fontHandler.getTextWidth(methodNameFromText) / span; double totalDist = lineSpaceRequiredForMessage - rectWidth + controlFlowBoxWidth; // add the rectWidth (because the text can exceed the half rect to the left and right and add the controlFlowBoxWidth to avoid text overlapping with control flow boxes rectDistance = (int) Math.max(rectDistance, totalDist); } } int arrowKind = -1; int lineKind = -1; boolean reverse = false; // arrow direction flag if (m.group(2).equals("->")) { arrowKind = ASYNC; lineKind = SOLID; } else if (m.group(2).equals("->>")) { arrowKind = SYNC; lineKind = SOLID; } else if (m.group(2).equals("-/>")) { arrowKind = EDGE; lineKind = SOLID; } // LME else if (m.group(2).equals("->>>")) { arrowKind = FILLED; lineKind = SOLID; } // LME else if (m.group(2).equals(".>")) { arrowKind = ASYNC; lineKind = DOTTED; } // LME else if (m.group(2).equals(".>>")) { arrowKind = SYNC; lineKind = DOTTED; } // LME else if (m.group(2).equals("./>")) { arrowKind = EDGE; lineKind = DOTTED; } // LME else if (m.group(2).equals(".>>>")) { arrowKind = FILLED; lineKind = DOTTED; } // LME else if (m.group(2).equals("<-")) { arrowKind = ASYNC; lineKind = SOLID; reverse = true; } else if (m.group(2).equals("<<-")) { arrowKind = SYNC; lineKind = SOLID; reverse = true; } else if (m.group(2).equals("= 0) { group += element.substring(element.indexOf("iframe")); // append info for interactionframe } } else // LABLING ADD { String[] grouparray = group.split(","); group = ""; for (String tmp : grouparray) { Integer tempgroup = labeltonumber.get(tmp); if (tempgroup != null) { group += "," + tempgroup; } } if (group.length() > 0) { group = group.substring(1); } else { if (grouparray.length == 1) { group = "#"; methodName = grouparray[0]; } } } // STOP LABLING ADD boxStrings += ";" + group; // LME: get alive Objects boolean srcObjHasControl = srcObj != null ? group.contains(String.valueOf(srcObj)) : false; boolean destObjHasControl = destObj != null ? group.contains(String.valueOf(destObj)) : false; if (methodName == null || methodName.isEmpty()) { methodName = methodNameFromText; } // LME: removed (in V6) since not necessary // if(destObj==srcObj) levelNum++; //LME: expand the Entity's size if (srcObj == null || destObj == null) { continue; } if (!reverse) { im.add(curLevel, new Interaction(srcObj, srcObjHasControl, arrowKind, lineKind, destObj, destObjHasControl, methodName)); // normal arrow direction 1->2 } else { im.add(curLevel, new Interaction(destObj, destObjHasControl, arrowKind, lineKind, srcObj, srcObjHasControl, methodName)); // reverse arrow direction 1<-2 } } // #for } // end message parsing // draw the first line of the sequence diagram int ypos = borderDistance + yOffsetforTitle; int xpos = borderDistance; for (int i = 0; i < numObjects; i++) { boolean underline = false; String s = obj.elementAt(i); if (s.startsWith(FormatLabels.UNDERLINE.getValue()) && s.endsWith(FormatLabels.UNDERLINE.getValue()) && s.length() > 2) { underline = true; s = s.substring(1, s.length() - 1); } TextLayout layout = new TextLayout(s, fontHandler.getFont(), g2.getFontRenderContext()); g2.drawRect(xpos, ypos, rectWidth - 1, rectHeight - 1); int dx = (rectWidth - 2 - (int) Math.floor(layout.getBounds().getWidth() + 1)) / 2; int dy = (rectHeight - 2 - (int) Math.floor(layout.getBounds().getHeight() + 1)) / 2; int tx = xpos + dx; int ty = ypos + dy + (int) layout.getBounds().getHeight(); layout.draw(g2, tx, ty); if (underline) { g2.drawLine(tx, ty + (int) fontHandler.getDistanceBetweenTexts() / 2, tx + (int) layout.getBounds().getWidth(), ty + (int) fontHandler.getDistanceBetweenTexts() / 2); } xpos += rectWidth + rectDistance; } // draw the messages int maxTextXpos = drawMessages(g2); maxTextXpos += 3 * fontHandler.getDistanceBetweenTexts(); // add extra space if (boxStrings.length() > 1) { try { drawControlFlowBoxesWithLines(g2, boxStrings.substring(1), numObjects); // LME: 1,2;1,2;... cut first ;-character } catch (ArrayIndexOutOfBoundsException e) { // do nothing: this exception is thrown, when entering text, // that is not rendered to an control flow box } } // set our component to the correct size int rWidth = rectWidth * numObjects + rectDistance * (numObjects - 1) + 2 * borderDistance; int rHeight = 2 * borderDistance + yOffsetforTitle + rectHeight + rectToFirstLevelDistance + levelNum * levelHeight; rWidth = rWidth > maxTextXpos ? rWidth : maxTextXpos; // align the borders to the grid rWidth += Main.getHandlerForElement(this).getGridSize() - rWidth % Main.getHandlerForElement(this).getGridSize(); rHeight += Main.getHandlerForElement(this).getGridSize() - rHeight % Main.getHandlerForElement(this).getGridSize(); setSize(rWidth, rHeight); } private void calcWidthOfLineHeaderBoxes(Graphics2D g2, FontHandler fontHandler, Vector obj, int numObjects) { // find out the width of the column with the longest text double maxWidth = 0; double maxHeight = 0; for (int i = 0; i < numObjects; i++) { String s = obj.elementAt(i); if (s.startsWith(FormatLabels.UNDERLINE.getValue()) && s.endsWith(FormatLabels.UNDERLINE.getValue()) && s.length() > 2) { s = s.substring(1, s.length() - 1); } TextLayout layout = new TextLayout(s, fontHandler.getFont(), g2.getFontRenderContext()); maxWidth = Math.max(layout.getBounds().getWidth(), maxWidth); maxHeight = Math.max(layout.getBounds().getHeight(), maxHeight); } rectWidth = (int) Math.floor(maxWidth + 1) + 2 * (int) fontHandler.getDistanceBetweenTexts() + (int) fontHandler.getFontSize(); rectHeight = (int) Math.floor(maxHeight + 1) + (int) fontHandler.getDistanceBetweenTexts() + (int) fontHandler.getFontSize(); } private int drawMessages(Graphics2D g2) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int maxTextXpos = 0; for (int i = 0; i < im.getNumLevels(); i++) { Set interactions = im.getInteractionsInLevel(i + 1); Iterator it = interactions.iterator(); while (it.hasNext()) { Interaction ia = it.next(); if (ia.getSrcObj() == ia.getDestObj()) { // draw an arc-arrow int xTextOffset = 0; int w = (int) (30 * zoom); int h = (int) (levelHeight * 0.66); int x = hCenterForObj(ia.getSrcObj()) - w / 2; // nt y= vCenterForLevel(i+1) - h/2; int ay = vCenterForLevel(i + 1) + (int) (5 * zoom); // + levelHeight/2 -1; if (im.controlBoxExists(i + 1, ia.getSrcObj())) { x += controlFlowBoxWidth / 2; xTextOffset = controlFlowBoxWidth / 2; } g2.drawArc(x, ay, w, h, 90, -180); Point p1 = new Point(x + w / 2, ay + h); Point d1 = new Point(x + w / 2 + (int) (3 * zoom), p1.y - (int) (6 * zoom)); Point d2 = new Point(x + w / 2 + (int) (4 * zoom), p1.y + (int) (4 * zoom)); if (ia.getArrowKind() == ASYNC) { // Pfeil offen g2.drawLine(p1.x, p1.y, d1.x, d1.y); g2.drawLine(p1.x, p1.y, d2.x, d2.y); } else if (ia.getArrowKind() == SYNC) { int[] xs = { p1.x, d1.x, d2.x }; int[] ys = { p1.y, d1.y, d2.y }; Color oldColor = g2.getColor(); g2.setColor(bgColor); g2.fillPolygon(xs, ys, 3); g2.setColor(oldColor); g2.drawPolygon(xs, ys, 3); } else if (ia.getArrowKind() == EDGE) { g2.drawLine(p1.x, p1.y, d2.x, d2.y); } else if (ia.getArrowKind() == FILLED) { Polygon p = new Polygon(); p.addPoint(p1.x, p1.y); p.addPoint(d1.x, d1.y); p.addPoint(d2.x, d2.y); g2.fillPolygon(p); } // print the methodname if (ia.getMethodName() != null && !ia.getMethodName().equals("")) { int fx1 = x + w + 2; int fy1 = ay; int fx2 = hCenterForObj(ia.getSrcObj()) + rectWidth / 2; int fy2 = ay + h; int tx = printMethodName(g2, ia.getMethodName(), fx1 + xTextOffset, fx2 + xTextOffset, fy1, fy2, true, false); maxTextXpos = maxTextXpos > tx ? maxTextXpos : tx; } } else { // draw an arrow from the source-object to the destination object int begX = hCenterForObj(ia.getSrcObj()); int endX = ia.getSrcObj() < ia.getDestObj() ? hCenterForObj(ia.getDestObj()) - 1 : hCenterForObj(ia.getDestObj()) + 1; int arrowY = vCenterForLevel(i + 1) + levelHeight / 2 - 1; if (ia.getSrcObjHasControl()) { // LME: shrink arrow if box exists begX += ia.getSrcObj() < ia.getDestObj() ? controlFlowBoxWidth / 2 : -controlFlowBoxWidth / 2; } if (ia.getDestObjHasControl()) { // LME: shrink arrow if box exists endX += ia.getSrcObj() < ia.getDestObj() ? -controlFlowBoxWidth / 2 : controlFlowBoxWidth / 2; } drawArrow(g2, new Point(begX, arrowY), new Point(endX, arrowY), ia.getArrowKind(), ia.getLineKind()); if (ia.getMethodName() != null && !ia.getMethodName().equals("")) { final int b = 2; if (ia.getSrcObj() < ia.getDestObj()) { int tx = printMethodName(g2, ia.getMethodName(), begX + b, endX - arrowX - b, arrowY - 1 - levelHeight / 1, arrowY - 1, false, true); maxTextXpos = maxTextXpos > tx ? maxTextXpos : tx; } else { int tx = printMethodName(g2, ia.getMethodName(), endX + arrowX + b, begX - b, arrowY - 1 - levelHeight / 2, arrowY - 1, false, true); maxTextXpos = maxTextXpos > tx ? maxTextXpos : tx; } } } } } return maxTextXpos; } // prints the given methodName in an intelligent manner into // the supplied rectangle. // The method may put pixels anywhere into the supplied rectangle // including the borders. (In other words eg. the point begX/endY // may be set by this method.) // if the fontsize gets very big this method may cross the vertical borders. private int printMethodName(Graphics2D g2, String methodName, int begX, int endX, int begY, int endY, boolean centerVertically, boolean centerHorizontically) { if (methodName == null || methodName.equals("")) { log.error("SequenceDiagram->printMethodName was called with an invalid argument."); return 0; } Font font = Main.getHandlerForElement(this).getFontHandler().getFont(); TextLayout layout = new TextLayout(methodName, font, g2.getFontRenderContext()); // draw it horizontally centered int dx = centerHorizontically ? (endX - begX - (int) layout.getBounds().getWidth()) / 2 : 0; int dy = centerVertically ? (endY - begY - (int) layout.getBounds().getHeight()) / 2 : 1; layout.draw(g2, begX + dx, endY - dy); return begX + dx + (int) layout.getBounds().getWidth(); } public void drawControlFlowBoxesWithLines(Graphics2D g2, String s, int numObjects) { // LME int level = 1; StringTokenizer mainTokens = new StringTokenizer(s, ";"); int tokNum = mainTokens.countTokens(); int[][] tField = new int[numObjects][tokNum + 2]; Vector interactionframes = new Vector(); HashMap interactionframesText = new HashMap(); // collect all tokens into an array: create another view to sequentially access data of a specific object // 1,2;#;1,3;1,3;1;3 will be transfomed to // tField: [110] // [000] // [101] // [101] // [100] // [001] while (mainTokens.hasMoreTokens()) { String main = mainTokens.nextToken(); if (main.indexOf("#") >= 0) { // if no box, clear entire row for (int i = 0; i < numObjects; i++) { tField[i][level - 1] = 0; // clear } if (main.indexOf("#iframe{") >= 0 || main.indexOf("#iframe}") >= 0) { if (main.indexOf("#iframe{") >= 0) { interactionframes.add(Integer.valueOf(level)); } else { interactionframes.add(Integer.valueOf(level * -1)); // distinguish betweeen start and end of the iframe } if (main.indexOf("iframe{:") >= 0) { interactionframesText.put("" + level, main.substring(main.indexOf("iframe{:") + 8)); // put text into hashmap } } level++; } else { StringTokenizer innerT = new StringTokenizer(main, ","); for (int i = 0; i < numObjects; i++) { tField[i][level - 1] = 0; // clear } while (innerT.hasMoreTokens()) { String is = innerT.nextToken(); int objNum = Integer.parseInt(is); tField[objNum - 1][level - 1] = 1; } level++; } // #else } // #while for (int actObjNum = 0; actObjNum < numObjects; actObjNum++) { // controlFlowBoxWidth = controlFlowBoxWidth * getHandler().getGridSize() / 10; // rectDistance = rectDistance / getHandler().getGridSize() / 10; // levelHeight = levelHeight / getHandler().getGridSize() / 10; int offset = 2; int objNum = actObjNum + 1; int x1 = hCenterForObj(objNum) - controlFlowBoxWidth / 2; int startLevel = -1, boxSize = 0; int lineX = hCenterForObj(actObjNum + 1); int lineY1 = borderDistance + yOffsetforTitle + rectHeight; for (int i = 0; i < tokNum + 1; i++) { if (tField[actObjNum][i] == 1) { if (startLevel == -1) { startLevel = i; } boxSize++; } if (tField[actObjNum][i] == 0 && startLevel != -1) { int y1 = vCenterForLevel(startLevel + offset) - levelHeight - 1; g2.drawRect(x1, y1, controlFlowBoxWidth - 1, levelHeight * boxSize); // draw the box g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); // #draw the line between the boxes g2.drawLine(lineX, lineY1, lineX, y1); // # g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); // # lineY1 = y1 + levelHeight * boxSize; // # startLevel = -1; boxSize = 0; } } // #for(int i // LME: draw the tail int lineY2 = borderDistance + yOffsetforTitle + rectHeight + levelNum * levelHeight + rectToFirstLevelDistance; g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); g2.drawLine(lineX, lineY1, lineX, lineY2); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } // #for(int actObjNum // LME: draw the interaction frames int fullSets = interactionframes.size() - interactionframes.size() % 2; if (fullSets >= 2) { int pos = 0; while (pos < fullSets) { pos = recurseInteractionFrames(g2, interactionframes, interactionframesText, pos, 0); pos++; } } } /** * Recusion level step of interactionframes * ie: * iframe{ * iframe{ * } * iframe{ * } * } */ public int recurseInteractionFrames(Graphics2D g2, Vector interactionframes, HashMap interactionframesText, int pos, int recursionLevel) { int pos1 = interactionframes.elementAt(pos); int posX; while (pos < interactionframes.size() && (posX = interactionframes.elementAt(pos)) > 0) { // traverse through iframes an same level pos1 = posX; pos++; pos = recurseInteractionFrames(g2, interactionframes, interactionframesText, pos, recursionLevel + 1); // step on level deeper into recursion if (pos1 <= 0) { return pos; } int pos2 = interactionframes.elementAt(pos) * -1; drawInteractionFrame(g2, pos1, pos2, recursionLevel, interactionframesText.get("" + pos1)); pos++; } return pos; } private void drawInteractionFrame(Graphics2D g2, int pos1, int pos2, int recursionLevel, String text) { float zoom = Main.getHandlerForElement(this).getZoomFactor(); int pos11 = (pos1 + 1) * levelHeight + yOffsetforTitle; int h = (pos2 - pos1) * levelHeight; int x = (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 2 + recursionLevel * 4; g2.drawRect(x, pos11, getRectangle().width - (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() * 4 - 1 - recursionLevel * 8, h); int uLinePos = pos11 + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) (Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts()); int textPos = pos11 + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize(); int textWidth = 0; if (text == null || text.equals("")) { text = " "; } g2.drawString(text, x + (int) (10 * zoom), textPos); int pW = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(text); textWidth = pW > textWidth ? pW : textWidth; g2.drawLine(x, uLinePos, x + textWidth + (int) (15 * zoom), uLinePos); g2.drawLine(x + textWidth + (int) (15 * zoom), uLinePos, x + textWidth + (int) (25 * zoom), pos11 + (int) (10 * zoom)); g2.drawLine(x + textWidth + (int) (25 * zoom), pos11, x + textWidth + (int) (25 * zoom), pos11 + (int) (10 * zoom)); } public void drawArrow(Graphics2D g2, Point srcObj, Point destObj, int arrowKind, int lineKind) { Point p1, p2; if (srcObj.x < destObj.x) { p1 = new Point(destObj.x - arrowX, destObj.y + arrowY); p2 = new Point(destObj.x - arrowX, destObj.y - arrowY); } else { p1 = new Point(destObj.x + arrowX, destObj.y + arrowY); p2 = new Point(destObj.x + arrowX, destObj.y - arrowY); } if (arrowKind == SYNC) { g2.drawLine(p1.x, p1.y, p2.x, p2.y); g2.drawLine(destObj.x, destObj.y, p1.x, p1.y); g2.drawLine(destObj.x, destObj.y, p2.x, p2.y); if (lineKind == DOTTED) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } g2.drawLine(srcObj.x, srcObj.y, p1.x, destObj.y); } else if (arrowKind == ASYNC) { g2.drawLine(destObj.x, destObj.y, p1.x, p1.y); g2.drawLine(destObj.x, destObj.y, p2.x, p2.y); if (lineKind == DOTTED) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } g2.drawLine(srcObj.x, srcObj.y, destObj.x, destObj.y); } else if (arrowKind == EDGE) { g2.drawLine(destObj.x, destObj.y, p2.x, p2.y); if (lineKind == DOTTED) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } g2.drawLine(srcObj.x, srcObj.y, destObj.x, destObj.y); } else if (arrowKind == FILLED) { Polygon p = new Polygon(); p.addPoint(p1.x, p1.y); p.addPoint(p2.x, p2.y); p.addPoint(destObj.x, destObj.y); g2.fillPolygon(p); if (lineKind == DOTTED) { g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); } g2.drawLine(srcObj.x, srcObj.y, p1.x, destObj.y); } g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } protected int hCenterForObj(int objNum) { return objNum * rectWidth + (objNum - 1) * rectDistance + borderDistance - rectWidth / 2; } protected int vCenterForLevel(int level) { return level * levelHeight + rectToFirstLevelDistance + rectHeight + borderDistance + yOffsetforTitle - levelHeight / 2; } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } public void zoomValues() { float zoom = Main.getHandlerForElement(this).getZoomFactor(); controlFlowBoxWidth = (int) (20 * zoom); rectDistance = (int) (rectDistance * zoom); borderDistance = (int) (10 * zoom); levelHeight = (int) (30 * zoom); arrowX = (int) (5 * zoom); arrowY = (int) (5 * zoom); } @Override public boolean isDeprecated() { return false; } @Override public GridElementDeprecatedAddons getDeprecatedAddons() { return new GridElementDeprecatedAddons() { @Override public void doBeforeExport() { // Issue 159: the old all in one grid elements calculate their real size AFTER painting. although it's bad design it works for most cases, but batch-export can fail if the element width in the uxf is wrong (eg if it was created using another umlet-default-fontsize), therefore a pseudo-paint call is made to get the real size paintEntity(new EpsGraphics2D()); } }; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/allinone/ActivityDiagramText.java0000644000175000017500000004034712533641120030377 0ustar benbenpackage com.baselet.element.old.allinone; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.sourceforge.jlibeps.epsgraphics.EpsGraphics2D; import com.baselet.control.Main; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.util.Utils; import com.baselet.element.interfaces.GridElementDeprecatedAddons; import com.baselet.element.old.OldGridElement; import com.baselet.element.old.activity.AEnd; import com.baselet.element.old.activity.Activity; import com.baselet.element.old.activity.Condition; import com.baselet.element.old.activity.Const; import com.baselet.element.old.activity.Container; import com.baselet.element.old.activity.Element; import com.baselet.element.old.activity.End; import com.baselet.element.old.activity.EndIf; import com.baselet.element.old.activity.EventRaise; import com.baselet.element.old.activity.EventRecieve; import com.baselet.element.old.activity.Fork; import com.baselet.element.old.activity.GoTo; import com.baselet.element.old.activity.If; import com.baselet.element.old.activity.LineSpacer; import com.baselet.element.old.activity.PartActivity; import com.baselet.element.old.activity.Row; import com.baselet.element.old.activity.Start; import com.baselet.element.old.activity.StartElement; import com.baselet.element.old.activity.StopElement; import com.baselet.element.old.activity.Sync; import com.baselet.element.sticking.StickingPolygon; @SuppressWarnings("serial") public class ActivityDiagramText extends OldGridElement { private final AtomicBoolean autoInsertIF = new AtomicBoolean(); private ArrayList rows; private ArrayList containers; private Container root_container; private Container current_container; private HashMap elements; private String title; private Graphics2D graphics; private ArrayList gotos; private int goto_seperation_left; private int goto_seperation_right; private float zoom; private static final String normalchars = "[^\\~\\>]";// "[ \\w\\\\\\(\\)]"; private static final String conditionChars = "[^\\]]"; private static final String title_pattern = "title\\:(" + normalchars + "+)"; private static final String line_pattern = "(\\t*)" + // tabs 1 "(\\[([ " + conditionChars + "]+)\\])?" + // conditions 2..3 "(" + // 4 "(" + // 5 "(Start)" + // start 6 "|(End|AEnd)" + // end7 "|(\\|)" + // linespacer 8 "|(If|Fork)|(EndIf|Sync)" + // if blocks 9/10 "|(While(\\[(" + normalchars + "*)\\])?)" + // while 11..13 "|(\\>(" + normalchars + "+))" + // recieve event 14..15 "|((" + normalchars + "+)\\>)" + // raise event 16..17 "|((" + normalchars + "+)\\.\\.)" + // partactivity 18..19 "|(" + normalchars + "+)" + // activity 20 ")" + "(\\~(" + normalchars + "+)?)?" + // ids 21..22 ")?" + "\\s*" + "(\\-\\>(" + normalchars + "+))?" + // goto 23..24 "\\s*"; private void init(Graphics2D graphics) { zoom = Main.getHandlerForElement(this).getZoomFactor(); this.graphics = graphics; rows = new ArrayList(); gotos = new ArrayList(); containers = new ArrayList(); elements = new HashMap(); rows.add(new Row()); root_container = new Container(autoInsertIF, Main.getHandlerForElement(this), graphics, null, rows, 0); current_container = root_container; title = null; goto_seperation_left = (int) (5 * zoom); goto_seperation_right = (int) (5 * zoom); // Some unimportant initialization stuff; setting color, font // quality, etc. You should not have to change this. this.graphics = graphics; this.graphics.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); this.graphics.setColor(fgColor); } private String preparse(String line) { String parsed_line = ""; Pattern p_empty = Pattern.compile("\\s*"); Pattern p_title = Pattern.compile(title_pattern); if (!p_empty.matcher(line).matches()) { Pattern p = Pattern.compile(line_pattern); Matcher m_title = p_title.matcher(line); if (m_title.matches()) { parsed_line = null; title = m_title.group(1); } else if (p.matcher(line).matches()) { parsed_line = line; } else { parsed_line = null; } } return parsed_line; } public int getGotoPosition(Direction dir) { if (Direction.LEFT.equals(dir)) { if (goto_seperation_left + Const.GOTO_SEP * zoom < Const.DIAGRAM_PAD * zoom) { goto_seperation_left += Const.GOTO_SEP * zoom; } return (int) (Const.DIAGRAM_PAD * zoom - goto_seperation_left); } else { if (goto_seperation_right + Const.GOTO_SEP * zoom < Const.DIAGRAM_PAD * zoom) { goto_seperation_right += Const.GOTO_SEP * zoom; } return (int) (root_container.getWidth() + Const.DIAGRAM_PAD * zoom + goto_seperation_right); } } private Vector preparse(Vector lines) { if (lines.isEmpty()) { return lines; } Vector parsed_lines = new Vector(); Iterator it = lines.iterator(); String current_line = this.preparse(it.next()); if (current_line == null) { current_line = ""; } while (current_line.equals("") && it.hasNext()) { current_line = this.preparse(it.next()); if (current_line == null) { current_line = ""; } } String previous_line = current_line; int current_depth = 0; int last_depth = 0; while (it.hasNext()) { current_line = this.preparse(it.next()); if (current_line != null) { if (!current_line.equals("")) { for (current_depth = 0; current_line.charAt(current_depth) == '\t'; current_depth++) {/* do nothing except increasing current depth */} if (!previous_line.equals("") || current_depth == last_depth) { parsed_lines.add(previous_line); } previous_line = current_line; last_depth = current_depth; } else if (!previous_line.equals("")) { parsed_lines.add(previous_line); previous_line = current_line; } } } if (!previous_line.equals("")) { parsed_lines.add(previous_line); } return parsed_lines; } private void addElement(Element e) { current_container.addElement(e); elements.put(e.getId(), e); } @Override public void paintEntity(Graphics g) { init((Graphics2D) g); Vector lines = Utils.decomposeStringsWithEmptyLines(getPanelAttributes()); lines = this.preparse(lines); if (lines.size() == 0) { return; } autoInsertIF.set(true); while (lines.size() > 0 && lines.elementAt(0).startsWith("var:")) { if (lines.elementAt(0).equals("var:noautoif")) { autoInsertIF.set(false); } lines.remove(0); } int current_depth = 0; Pattern p = Pattern.compile(line_pattern); StartElement start_element = null; Element current_element = null; containers.add(root_container); for (String line : lines) { Matcher m = p.matcher(line); Container closed_container = null; if (m.matches()) { Pattern p_empty = Pattern.compile("\\s*"); Matcher m_empty = p_empty.matcher(line); /* NEW COLUMN IN CURRENT LAYER */ if (m_empty.matches()) { /* start element was no start element (example: IF element without following container) */ if (start_element != null) { addElement(start_element); start_element = null; } if (!current_container.isRoot()) { current_container.addColumn(); } // empty line - no need to proceed with other stuff continue; } /* DEPTH */ if (m.group(1) != null) { /* NEW LAYER */ if (m.group(1).length() > current_depth) { for (; current_depth < m.group(1).length(); current_depth++) { current_container = current_container.addNewContainer(); containers.add(current_container); if (start_element != null) { current_container.setStartElement(start_element); elements.put(start_element.getId(), start_element); start_element = null; } } } else { /* start element was no start element (example: IF element without following container) */ if (start_element != null) { addElement(start_element); start_element = null; } /* CLOSE LAYER(s) */ if (m.group(1).length() < current_depth) { for (; current_depth > m.group(1).length(); current_depth--) { closed_container = current_container; if (!current_container.isRoot()) { current_container = current_container.close(); } } } } } Element e = null; /* BEDINGUNG */ if (m.group(2) != null) { String input = ""; if (m.group(3) != null) { input = m.group(3); } e = new Condition(Main.getHandlerForElement(this), input, graphics); current_element = e; } if (e != null) { addElement(e); } e = null; if (m.group(4) != null) { String id = m.group(22); /* START */ if (m.group(6) != null) { e = new Start(Main.getHandlerForElement(this), graphics); } /* END */ else if (m.group(7) != null) { if (m.group(7).equals("AEnd")) { e = new AEnd(Main.getHandlerForElement(this), graphics, id); } else { e = new End(Main.getHandlerForElement(this), graphics, id); } } /* LINESPACER */ else if (m.group(8) != null) { e = new LineSpacer(Main.getHandlerForElement(this), graphics); } /* IF/FORK */ else if (m.group(9) != null) { // these elements are processed as soon as a the // new container is opened (or as single elements // if none is openend if (m.group(9).equals("Fork")) { start_element = new Fork(Main.getHandlerForElement(this), graphics, id); } else { start_element = new If(Main.getHandlerForElement(this), graphics, id); } current_element = start_element; } /* ENDIF/SYNC */ else if (m.group(10) != null) { // set as stop element if a container has been closed StopElement se; if (m.group(10).equals("Sync")) { se = new Sync(Main.getHandlerForElement(this), graphics, id); } else { se = new EndIf(Main.getHandlerForElement(this), graphics, id); } if (closed_container != null) { closed_container.setStopElement(se); elements.put(se.getId(), se); } else { e = se; } current_element = se; } /* WHILE */ else if (m.group(11) != null) { current_container = current_container.addNewWhile(m.group(13)); current_depth++; } /* GET EVENT */ else if (m.group(15) != null) { e = new EventRecieve(Main.getHandlerForElement(this), graphics, m.group(15), id); } else if (m.group(17) != null) { e = new EventRaise(Main.getHandlerForElement(this), graphics, m.group(17), id); } else if (m.group(19) != null) { e = new PartActivity(Main.getHandlerForElement(this), m.group(19), graphics, id); } else if (m.group(20) != null) { e = new Activity(Main.getHandlerForElement(this), m.group(20), graphics, id); } } if (e != null) { current_element = e; addElement(e); } /* GOTO */ if (m.group(23) != null) { if (m.group(24) != null && current_element != null) { String connect_to = m.group(24); gotos.add(new GoTo(graphics, current_element, connect_to)); current_element.setTerminated(); } } } } // if a Startelement was the last element if (start_element != null) { addElement(start_element); } // close opened containers while (!current_container.isRoot()) { current_container = current_container.close(); } // remove empty columns of containers (maybe there if only a goto element was there) for (Container c : containers) { c.removeEmptyColumns(); } // PROCESS GOTO ELEMENTS ArrayList valid_gotos = new ArrayList(); for (GoTo go : gotos) { Element from = go.getFromElement(); go.setToElement(elements.get(go.getToElementId())); Element to = go.getToElement(); if (from != null && to != null) { valid_gotos.add(go); boolean fromleft = from.getRow().isLeft(from); boolean fromright = from.getRow().isRight(from); boolean toleft = to.getRow().isLeft(to); boolean toright = to.getRow().isRight(to); if (fromleft) { go.setDirection(Direction.LEFT); if (!toleft) { rows = to.getRow().makeExclusiveLeft(to, rows); } } else if (toleft) { go.setDirection(Direction.LEFT); rows = from.getRow().makeExclusiveLeft(from, rows); } else if (fromright) { go.setDirection(Direction.RIGHT); if (!toright) { rows = to.getRow().makeExclusiveRight(to, rows); } } else if (toright) { go.setDirection(Direction.RIGHT); rows = from.getRow().makeExclusiveRight(from, rows); } else { go.setDirection(Direction.LEFT); rows = from.getRow().makeExclusiveLeft(from, rows); rows = to.getRow().makeExclusiveLeft(to, rows); } } } // draw title int offset = 0; int width = (int) (root_container.getWidth() + Const.DIAGRAM_PAD * zoom * 2); int height = 0; if (title != null) { offset += (int) (25 * zoom); height += (int) (25 * zoom); if (title.length() > 0) { Main.getHandlerForElement(this).getFontHandler().writeText(graphics, title, (int) (10 * zoom), (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts(), AlignHorizontal.LEFT); int titlewidth = (int) Main.getHandlerForElement(this).getFontHandler().getTextWidth(title); int ty = (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() + (int) Main.getHandlerForElement(this).getFontHandler().getDistanceBetweenTexts() + (int) (8 * zoom); graphics.drawLine(0, ty, titlewidth + (int) (10 * zoom), ty); graphics.drawLine(titlewidth + (int) (10 * zoom), ty, titlewidth + ty + (int) (10 * zoom), 0); } } /* COMPUTE POSITIONS */ for (Row r : rows) { offset = r.setElementYPosition(offset); } root_container.setX((int) (root_container.getLeftWidth() + Const.DIAGRAM_PAD * zoom)); if (Const.DEBUG) { root_container.printData(""); } for (Row r : rows) { height += r.getHeight(); } if (width < Const.MIN_WIDTH * zoom) { width = (int) (Const.MIN_WIDTH * zoom); } if (height < Const.MIN_HEIGHT * zoom) { height = (int) (Const.MIN_HEIGHT * zoom); } // draw diagram this.setSize(width, height); graphics.drawRect(0, 0, getRectangle().width - 1, getRectangle().height - 1); root_container.paint(); // draw goto elements for (GoTo goTo : valid_gotos) { goTo.paint(Main.getHandlerForElement(this).getZoomFactor(), getGotoPosition(goTo.getDirection())); } } @Override public Set getResizeArea(int x, int y) { return new HashSet(); // deny size changes } @Override public StickingPolygon generateStickingBorder() { return null; } @Override public boolean isDeprecated() { return false; } @Override public GridElementDeprecatedAddons getDeprecatedAddons() { return new GridElementDeprecatedAddons() { @Override public void doBeforeExport() { // Issue 159: the old all in one grid elements calculate their real size AFTER painting. although it's bad design it works for most cases, but batch-export can fail if the element width in the uxf is wrong (eg if it was created using another umlet-default-fontsize), therefore a pseudo-paint call is made to get the real size paintEntity(new EpsGraphics2D()); } }; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/0000755000175000017500000000000012533641120023631 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Start.java0000644000175000017500000000125312533641120025572 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.diagram.DiagramHandler; public class Start extends Element { public Start(DiagramHandler handler, Graphics2D g) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), null); setWidth((int) (21 * getZoom())); setHeight((int) (21 * getZoom())); } @Override public boolean connectIn() { return false; } @Override public void paint() { Point cord = getPosition(); getGraphics().fillArc(cord.x - (int) (10 * getZoom()), cord.y - (int) (10 * getZoom()), (int) (21 * getZoom()), (int) (21 * getZoom()), 0, 360); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Label.java0000644000175000017500000000240712533641120025516 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.Rectangle2D; import com.baselet.diagram.DiagramHandler; public class Label extends Element { private String[] label; private int line_height; public Label(DiagramHandler handler, String label, Graphics2D g, int padding) { super(handler, g, padding, null); this.label = label.split("\\\\"); int w = 0, h = 0; for (String element : this.label) { Rectangle2D rect = g.getFont().getStringBounds(element, g.getFontRenderContext()); w = w < (int) (rect.getMaxX() - rect.getMinX()) ? (int) (rect.getMaxX() - rect.getMinX()) : w; h += (int) (rect.getMaxY() - rect.getMinY()); line_height = (int) (rect.getMaxY() - rect.getMinY()); } setWidth(w); setHeight(h); } @Override public boolean connectIn() { return false; } @Override public boolean connectOut_overrideable() { return false; } @Override public void paint() { Point cord = getPosition(); int y = cord.y - getHeight() / 2 - getPadding(); for (int i = 0; i < label.length; i++) { getGraphics().drawString(label[i], cord.x - getWidth() / 2, y + getHeight() - (label.length - i - 1) * line_height - 1); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Fork.java0000644000175000017500000000712012533641120025375 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class Fork extends StartElement { private int h = (int) (4 * getZoom()); // pad for the connectors private int pad = (int) (20 * getZoom()); private int w = (int) (80 * getZoom()); // padding between connectors private int con_pad = (int) (10 * getZoom()); private Integer current_left_x; private Integer current_right_x; public Fork(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), id == null ? "Fork" : id); setHeight(h + pad); setWidth(w); } @Override public void paint() { int x = getPosition().x; int y = getPosition().y; getGraphics().fillRect(x - w / 2, y - (h + pad) / 2, w, (int) (4 * getZoom())); } @Override public boolean arrowIn() { return true; } @Override protected Point getNonStdConnectIn(Direction dir) { Point c = getConnect(Direction.UP); if (dir.equals(Direction.LEFT)) { c.x -= (int) (10 * getZoom()); } else if (dir.equals(Direction.RIGHT)) { c.x += (int) (10 * getZoom()); } if (arrowIn()) { Connector.drawArrow(getGraphics(), getZoom(), c.x, c.y - (int) (10 * getZoom()), c.x, c.y); } else { getGraphics().drawLine(c.x, c.y - (int) (10 * getZoom()), c.x, c.y); } c.y -= (int) (10 * getZoom()); return c; } @Override protected Point getNonStdConnectOut(Direction dir) { Point c = getConnect(dir); if (dir.equals(Direction.LEFT)) { getGraphics().drawLine(c.x - (int) (10 * getZoom()), c.y + (int) (3 * getZoom()), c.x, c.y); c.x -= (int) (10 * getZoom()); c.y += (int) (3 * getZoom()); } else if (dir.equals(Direction.RIGHT)) { getGraphics().drawLine(c.x + (int) (10 * getZoom()), c.y + (int) (3 * getZoom()), c.x, c.y); c.x += (int) (10 * getZoom()); c.y += (int) (3 * getZoom()); } return c; } @Override protected Point getConnect(Direction dir) { Point c = (Point) getPosition().clone(); if (current_left_x == null) { current_left_x = getPosition().x; current_right_x = current_left_x; } if (dir == Direction.UP) { c.y -= (pad + h) / 2; } else if (dir == Direction.DOWN) { c.y += (h - pad) / 2; } else if (dir == Direction.LEFT) { if (c.x - current_left_x < w / 2 - con_pad) { current_left_x -= con_pad; } c.x = current_left_x; c.y += (h - pad) / 2; } else if (dir == Direction.RIGHT) { if (current_right_x - c.x < w / 2 - con_pad) { current_right_x += con_pad; } c.x = current_right_x; c.y += (h - pad) / 2; } return c; } @Override public void connectTo(Element e) { if (e != null) { if (connectOut_overrideable() && e.connectIn()) { Point from = getPosition(); Point to = e.getConnect(Direction.UP); if (from.x == to.x) { from = getConnect(Direction.DOWN); } else if (from.x < to.x) { from = getConnect(Direction.RIGHT); } else if (from.x > to.x) { from = getConnect(Direction.LEFT); } if (from.x != to.x) { getGraphics().drawLine(from.x, from.y, to.x, to.y - (int) (Const.PAD * getZoom()) * 2); from.x = to.x; from.y = (int) (to.y - Const.PAD * getZoom() * 2); } if (arrowOut() && e.arrowIn()) { Connector.drawArrow(getGraphics(), getZoom(), from.x, from.y, to.x, to.y); } else { getGraphics().drawLine(from.x, from.y, to.x, to.y); } } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Connector.java0000644000175000017500000000311712533641120026430 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; public class Connector { private Element e1, e2; private Graphics2D graphics; public static void drawArrow(Graphics2D graphics, float zoom, int x1, int y1, int x2, int y2) { double ax1, ax2, ay1, ay2; int ax_1, ax_2, ay_1, ay_2; double angle = Math.atan2(y2 - y1, x2 - x1); ax1 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) - (int) (7 * zoom); ax2 = ax1; ay1 = -(int) (4 * zoom); ay2 = (int) (5 * zoom); ax_1 = (int) (Math.cos(angle) * ax1 - Math.sin(angle) * ay1) + x1; ay_1 = (int) (Math.sin(angle) * ax1 + Math.cos(angle) * ay1) + y1; ax_2 = (int) (Math.cos(angle) * ax2 - Math.sin(angle) * ay2) + x1; ay_2 = (int) (Math.sin(angle) * ax2 + Math.cos(angle) * ay2) + y1; graphics.drawLine(x1, y1, x2, y2); graphics.drawLine(x2, y2, ax_1, ay_1); graphics.drawLine(x2, y2, ax_2, ay_2); } public Connector(Graphics2D g, Element e1, Element e2) { graphics = g; this.e1 = e1; this.e2 = e2; } public void paint() { if (e1.connectOut() && e2.connectIn()) { Point c2 = e2.getConnect(Direction.UP); Point c1 = e1.getConnect(Direction.DOWN); if (c1 != null && c2 != null) { if (!c1.equals(c2)) { if (e1.arrowOut() && e2.arrowIn()) { float zoom = e1.getHandler().getZoomFactor(); Connector.drawArrow(graphics, zoom, c1.x, c1.y, c2.x, c2.y); } else { graphics.drawLine(c1.x, c1.y, c2.x, c2.y); } } } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/StopElement.java0000644000175000017500000000261512533641120026737 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class StopElement extends Element { public StopElement(DiagramHandler handler, Graphics2D g, int padding, String id) { super(handler, g, padding, id); } @Override public void paint() { } @Override public boolean arrowIn() { return false; } public void connectTo(Element e) { if (e != null) { if (connectIn() && e.connectOut()) { Point to = getPosition(); Point from = e.getConnect(Direction.DOWN); if (from.x == to.x) { to = getConnect(Direction.UP); } else if (from.x < to.x) { to = getConnect(Direction.LEFT); } else if (from.x > to.x) { to = getConnect(Direction.RIGHT); } if (from.x != to.x) { getGraphics().drawLine(from.x, from.y, from.x, to.y); if (arrowIn() && e.arrowOut()) { Connector.drawArrow(getGraphics(), getZoom(), from.x, to.y, to.x, to.y); } else { getGraphics().drawLine(from.x, to.y, to.x, to.y); } } else { if (arrowIn() && e.arrowOut()) { Connector.drawArrow(getGraphics(), getZoom(), from.x, from.y, to.x, to.y); } else { getGraphics().drawLine(from.x, from.y, to.x, to.y); } } } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/End.java0000644000175000017500000000154712533641120025211 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.diagram.DiagramHandler; public class End extends Element { public End(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), id == null ? "End" : id); setWidth((int) (21 * getZoom())); setHeight((int) (21 * getZoom())); } @Override public boolean connectOut_overrideable() { return false; } @Override public void paint() { Point cord = getPosition(); getGraphics().drawArc(cord.x - (int) (10 * getZoom()), cord.y - (int) (10 * getZoom()), (int) (21 * getZoom()), (int) (21 * getZoom()), 0, 360); getGraphics().fillArc(cord.x - (int) (6 * getZoom()), cord.y - (int) (6 * getZoom()), (int) (13 * getZoom()), (int) (13 * getZoom()), 0, 360); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Sync.java0000644000175000017500000000661212533641120025415 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class Sync extends StopElement { private int h = (int) (4 * getZoom()); // pad for the connectors private int pad = (int) (20 * getZoom()); private int w = (int) (80 * getZoom()); // padding between connectors private int con_pad = (int) (10 * getZoom()); private Integer current_left_x; private Integer current_right_x; public Sync(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * 2 * handler.getZoomFactor()), id == null ? "Sync" : id); setHeight(h + pad); setWidth(w); } @Override public void paint() { int x = getPosition().x; int y = getPosition().y; getGraphics().fillRect(x - w / 2, y + (pad - h) / 2, w, (int) (4 * getZoom())); } @Override public boolean arrowIn() { return true; } @Override protected Point getNonStdConnectIn(Direction dir) { Point c = getConnect(dir); Point c2 = (Point) c.clone(); if (dir.equals(Direction.LEFT)) { c2.x -= (int) (10 * getZoom()); } else if (dir.equals(Direction.RIGHT)) { c2.x += (int) (10 * getZoom()); } c2.y -= (int) (10 * getZoom()); if (arrowIn()) { Connector.drawArrow(getGraphics(), getZoom(), c2.x, c2.y, c.x, c.y); } else { getGraphics().drawLine(c2.x, c2.y, c.x, c.y); } return c2; } @Override protected Point getNonStdConnectOut(Direction dir) { Point c = getConnect(Direction.DOWN); if (dir.equals(Direction.LEFT)) { c.x -= (int) (10 * getZoom()); } else if (dir.equals(Direction.RIGHT)) { c.x += (int) (10 * getZoom()); } getGraphics().drawLine(c.x, c.y + (int) (5 * getZoom()), c.x, c.y); c.y += (int) (5 * getZoom()); return c; } @Override protected Point getConnect(Direction dir) { Point c = (Point) getPosition().clone(); if (current_left_x == null) { current_left_x = getPosition().x; current_right_x = current_left_x; } if (dir == Direction.UP) { c.y += (pad - h) / 2; } else if (dir == Direction.DOWN) { c.y += (pad + h) / 2; } else if (dir == Direction.LEFT) { if (c.x - current_left_x < w / 2 - con_pad) { current_left_x -= con_pad; } c.x = current_left_x; c.y += (pad - h) / 2; } else if (dir == Direction.RIGHT) { if (current_right_x - c.x < w / 2 - con_pad) { current_right_x += con_pad; } c.x = current_right_x; c.y += (pad - h) / 2; } return c; } @Override public void connectTo(Element e) { if (e != null) { if (connectIn() && e.connectOut()) { Point to = getPosition(); Point from = e.getConnect(Direction.DOWN); if (from.x == to.x) { to = getConnect(Direction.UP); } else if (from.x < to.x) { to = getConnect(Direction.LEFT); } else if (from.x > to.x) { to = getConnect(Direction.RIGHT); } if (from.x != to.x) { getGraphics().drawLine(from.x, from.y, from.x, to.y - (int) (Const.PAD * 2 * getZoom())); from.y = to.y - (int) (Const.PAD * 2 * getZoom()); } if (arrowIn() && e.arrowOut()) { Connector.drawArrow(getGraphics(), getZoom(), from.x, from.y, to.x, to.y); } else { getGraphics().drawLine(from.x, from.y, to.x, to.y); } } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/LineSpacer.java0000644000175000017500000000141312533641120026520 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class LineSpacer extends WhileElement { public LineSpacer(DiagramHandler handler, Graphics2D g) { super(handler, g, 0, null); setHeight((int) (Const.PAD * 2 * getZoom())); setWidth((int) (Const.PAD * 6 * getZoom())); } @Override public boolean arrowIn() { return false; } @Override protected Point getNonStdConnectOut(Direction dir) { return getConnect(Direction.DOWN); } @Override public void paint() { int h = getHeight() / 2; Point cord = getPosition(); getGraphics().drawLine(cord.x, cord.y - h, cord.x, cord.y + h); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/EventRecieve.java0000644000175000017500000000253112533641120027061 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class EventRecieve extends Activity { private int width = (int) (15 * getZoom()); public EventRecieve(DiagramHandler handler, Graphics2D g, String label, String id) { super(handler, label, g, id == null ? label : id); setLeftWidth(width); } @Override public boolean connectIn() { return false; } @Override protected Point getNonStdConnectOut(Direction dir) { if (dir.equals(Direction.LEFT)) { Point c = getConnect(Direction.DOWN); Point c2 = getConnect(Direction.LEFT); c.x = c2.x + width; getGraphics().drawLine(c.x, c.y, c.x, c.y + (int) (3 * getZoom())); c.y += (int) (3 * getZoom()); return c; } else { return getConnect(dir); } } @Override public void paint() { int bh = getHeight() / 2; Point cord = getPosition(); int uh = cord.y - (getHeight() - bh); bh += cord.y; label.paint(); int[] xPoints = { cord.x - getLeftWidth(), cord.x + getRightWidth(), cord.x + getRightWidth(), cord.x - getLeftWidth(), cord.x - getLeftWidth() + width }; int[] yPoints = { uh, uh, bh, bh, cord.y }; getGraphics().drawPolygon(xPoints, yPoints, xPoints.length); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/EventRaise.java0000644000175000017500000000167712533641120026554 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.diagram.DiagramHandler; public class EventRaise extends Activity { private int width = (int) (15 * getZoom()); public EventRaise(DiagramHandler handler, Graphics2D g, String label, String id) { super(handler, label, g, id == null ? label : id); setRightWidth(width); } @Override public boolean connectOut_overrideable() { return false; } @Override public void paint() { int bh = getHeight() / 2; Point cord = getPosition(); int uh = cord.y - (getHeight() - bh); bh += cord.y; label.paint(); int[] xPoints = { cord.x - getLeftWidth(), cord.x + getRightWidth() - width, cord.x + getRightWidth(), cord.x + getRightWidth() - width, cord.x - getLeftWidth() }; int[] yPoints = { uh, uh, cord.y, bh, bh }; getGraphics().drawPolygon(xPoints, yPoints, xPoints.length); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Row.java0000644000175000017500000000352112533641120025244 0ustar benbenpackage com.baselet.element.old.activity; import java.util.ArrayList; public class Row { private ArrayList elements; public Row() { elements = new ArrayList(); } public void exchangeElementOrInsert(Element old_element, Element new_element) { if (elements.contains(old_element)) { elements.set(elements.indexOf(old_element), new_element); } else { addElement(new_element); } new_element.setRow(this); } public boolean isLeft(Element e) { if (e.equals(elements.get(0))) { return true; } return false; } public boolean isRight(Element e) { if (e.equals(elements.get(elements.size() - 1))) { return true; } return false; } public ArrayList makeExclusiveLeft(Element e, ArrayList rows) { Row new_row = new Row(); int index = elements.indexOf(e); for (int i = 0; i < index; i++) { new_row.addElement(elements.get(0)); elements.remove(0); } rows.add(rows.indexOf(this) + 1, new_row); return rows; } public ArrayList makeExclusiveRight(Element e, ArrayList rows) { Row new_row = new Row(); int index = elements.indexOf(e); int size = elements.size(); for (int i = index + 1; i < size; i++) { new_row.addElement(elements.get(index + 1)); elements.remove(index + 1); } rows.add(rows.indexOf(this) + 1, new_row); return rows; } public void addElement(Element e) { elements.add(e); e.setRow(this); } public int setElementYPosition(int offset) { int h = getHeight(); int y = offset + h / 2; for (Element e : elements) { e.setY(y); } return offset + h; } public int getHeight() { int height = 0; for (Element e : elements) { int h = e.getHeight() + e.getPadding() * 2; if (h > height) { height = h; } } return height; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/PartActivity.java0000644000175000017500000000350212533641120027117 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.diagram.DiagramHandler; public class PartActivity extends Activity { private int minwidth = (int) (120 * getZoom()); private int height = (int) (20 * getZoom()); public PartActivity(DiagramHandler handler, String label, Graphics2D g, String id) { super(handler, label, g, id == null ? label : id); setHeight(height); } @Override protected int getLeftWidth() { return super.getLeftWidth() > minwidth / 2 ? super.getLeftWidth() : minwidth / 2; } @Override protected int getRightWidth() { return super.getRightWidth() > minwidth / 2 ? super.getRightWidth() : minwidth / 2; } @Override public void paint() { Point cord = getPosition(); int h = getHeight(); label.paint(); getGraphics().drawRoundRect(cord.x - getLeftWidth(), cord.y - h / 2, getWidth(), h, (int) (20 * getZoom()), (int) (20 * getZoom())); getGraphics().drawRoundRect(cord.x - minwidth / 4, cord.y + h / 2 - height + (int) (5 * getZoom()), (int) (30 * getZoom()), (int) (10 * getZoom()), (int) (10 * getZoom()), (int) (10 * getZoom())); getGraphics().drawRoundRect(cord.x + (int) (15 * getZoom()), cord.y + h / 2 - height + (int) (5 * getZoom()), (int) (30 * getZoom()), (int) (10 * getZoom()), (int) (10 * getZoom()), (int) (10 * getZoom())); int x1 = cord.x - minwidth / 4 + (int) (30 * getZoom()); int x2 = cord.x + (int) (15 * getZoom()); int y = cord.y + h / 2 - height / 2; getGraphics().drawLine(x1, y, x2, y); getGraphics().drawLine(x2, y, x2 - (int) (3 * getZoom()), y - (int) (2 * getZoom())); getGraphics().drawLine(x2, y, x2 - (int) (3 * getZoom()), y + (int) (2 * getZoom())); } @Override public void setY(int y) { super.setY(y); label.setY(y - height / 2); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/GoTo.java0000644000175000017500000000272612533641120025353 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; public class GoTo { private final Graphics2D graphics; private final String to_id; private final Element from_element; private Element to_element; private Direction dir; public GoTo(Graphics2D g, Element from, String to) { graphics = g; to_id = to; from_element = from; } public void setDirection(Direction dir) { this.dir = dir; } public Direction getDirection() { return dir; } public Element getFromElement() { return from_element; } public Element getToElement() { return to_element; } public String getToElementId() { return to_id; } public void setToElement(Element e) { to_element = e; } public void paint(float zoomFactor, int gotoPosition) { if (from_element.connectOut_overrideable() && to_element.connectIn() && to_element.arrowIn()) { Point from = from_element.getNonStdConnectOut(dir); Point to = to_element.getNonStdConnectIn(dir); Point to_origin = to_element.getConnect(dir); int x = gotoPosition; graphics.drawLine(from.x, from.y, x, from.y); graphics.drawLine(x, from.y, x, to.y); if (to.x == to_origin.x && to.y == to_origin.y) { float zoom = zoomFactor; Connector.drawArrow(graphics, zoom, x, to.y, to.x, to.y); } else { graphics.drawLine(x, to.y, to.x, to.y); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/While.java0000644000175000017500000000403212533641120025543 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import com.baselet.diagram.DiagramHandler; public class While extends Container { private WhileElement while_element; public While(AtomicBoolean autoInsertIF, DiagramHandler handler, Graphics2D g, Container parent, ArrayList rows, int row, String condition) { super(autoInsertIF, handler, g, parent, rows, row); if (condition != null && !condition.equals("")) { while_element = new Condition(handler, condition, g); } else { while_element = new LineSpacer(handler, g); } super.setStartElement(new If(handler, g, null)); addElement(while_element); addColumn(); } @Override public int getLeftWidth() { int width = getColumns().get(0).getWidth(); if (getColumns().size() > 1) { width += getColumns().get(1).getLeftWidth() + Const.COLUMN_PAD * getZoom(); } return width; } @Override protected int getRightWidth() { int width = 0; ArrayList columns = getColumns(); if (columns.size() > 1) { width += columns.get(1).getRightWidth(); } for (int i = 2; i < columns.size(); i++) { width += columns.get(i).getWidth() + Const.COLUMN_PAD * getZoom(); } return width; } @Override public void paint() { getStartElement().setNotTerminated(); getStartElement().paint(); getStopElement().paint(); while_element.connectTo(getStartElement(), getStopElement()); while_element.paint(); ArrayList columns = getColumns(); for (int i = 1; i < columns.size(); i++) { Column c = columns.get(i); getStartElement().connectTo(c.getFirstElement()); c.paint(); getStopElement().connectTo(c.getLastElement()); } } // dont allow change of start/stop elements @Override public void setStartElement(StartElement e) { } @Override public void setStopElement(StopElement e) { super.setStopElement(new EndIf(getHandler(), getGraphics(), null)); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/If.java0000644000175000017500000000147112533641120025035 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import com.baselet.diagram.DiagramHandler; public class If extends StartElement { private int h = (int) (40 * getZoom()); private int w = (int) (40 * getZoom()); public If(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), id == null ? "If" : id); setHeight(h); setWidth(w); } @Override public void paint() { int x = getPosition().x; int y = getPosition().y; getGraphics().drawLine(x, y - h / 2, x + w / 2, y); getGraphics().drawLine(x, y - h / 2, x - w / 2, y); getGraphics().drawLine(x, y + h / 2, x + w / 2, y); getGraphics().drawLine(x, y + h / 2, x - w / 2, y); } @Override public boolean arrowIn() { return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Condition.java0000644000175000017500000000464312533641120026431 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class Condition extends WhileElement { private Label label; public Condition(DiagramHandler handler, String label, Graphics2D g) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), null); setLeftWidth((int) (20 * getZoom())); this.label = new Label(handler, label, g, (int) (6 * getZoom())); } @Override public boolean arrowIn() { return false; } @Override protected int getHeight() { return super.getHeight() + label.getHeight() + label.getPadding() * 2; } @Override protected int getLeftWidth() { return super.getLeftWidth(); } @Override protected int getRightWidth() { return label.getWidth() + super.getRightWidth() + label.getPadding() * 2; } @Override public void setY(int y) { super.setY(y); label.setY(y); } @Override public void setX(int x) { super.setX(x); label.setX(x + label.getLeftWidth() + label.getPadding()); } @Override protected Point getNonStdConnectOut(Direction dir) { Point c = getConnect(Direction.DOWN); getGraphics().drawLine(c.x, c.y, c.x, c.y + (int) (5 * getZoom())); c.y += (int) (5 * getZoom()); return c; } @Override public void paint() { Point cord = getPosition(); int h = getHeight(); int width = label.getWidth() + label.getPadding() * 2; int height = label.getHeight() / 2 + label.getPadding(); int pad = label.getPadding(); // draw connector line getGraphics().drawLine(cord.x, cord.y - h / 2, cord.x, cord.y + h - h / 2); // draw left bracket getGraphics().drawLine(cord.x + pad / 2, cord.y - height, cord.x + pad / 2, cord.y + height); getGraphics().drawLine(cord.x + pad / 2, cord.y - height, cord.x + pad / 2 + (int) (5 * getZoom()), cord.y - height); getGraphics().drawLine(cord.x + pad / 2, cord.y + height, cord.x + pad / 2 + (int) (5 * getZoom()), cord.y + height); label.paint(); // draw right bracket getGraphics().drawLine(cord.x + width, cord.y - height, cord.x + width, cord.y + height); getGraphics().drawLine(cord.x + width, cord.y - height, cord.x + width - (int) (5 * getZoom()), cord.y - height); getGraphics().drawLine(cord.x + width, cord.y + height, cord.x + width - (int) (5 * getZoom()), cord.y + height); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Container.java0000644000175000017500000001716012533641120026423 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class Container extends Element { private final ArrayList columns; private StartElement start; private StopElement stop; private final Container parent; private final ArrayList rows; private int max_row; private int current_row; private int init_row; private final AtomicBoolean autoInsertIF; public Container(AtomicBoolean autoInsertIF, DiagramHandler handler, Graphics2D g, Container parent, ArrayList rows, int row) { super(handler, g, 0, null); columns = new ArrayList(); columns.add(new Column(g)); this.rows = rows; init_row = row; max_row = row; current_row = row; this.parent = parent; this.autoInsertIF = autoInsertIF; if (autoInsertIF.get() && this.parent != null) { setStartElement(new If(handler, g, null)); } else if (this.parent != null) { setStartElement(new StartElement(handler, g, 0, null)); } } public Container addNewContainer() { Container c = new Container(autoInsertIF, getHandler(), getGraphics(), this, rows, current_row); columns.get(columns.size() - 1).addElement(c); return c; } public Container addNewWhile(String condition) { Container c = new While(autoInsertIF, getHandler(), getGraphics(), this, rows, current_row, condition); columns.get(columns.size() - 1).addElement(c); return c; } protected ArrayList getColumns() { return columns; } protected Column getLastColumn() { return columns.get(columns.size() - 1); } public boolean isRoot() { if (parent == null) { return true; } return false; } public Container close() { if (autoInsertIF.get() && parent != null) { setStopElement(new EndIf(getHandler(), getGraphics(), null)); } else if (parent != null) { setStopElement(new StopElement(getHandler(), getGraphics(), 0, null)); } return parent; } private Row getNextRow() { while (rows.size() <= current_row) { rows.add(new Row()); } return rows.get(current_row); } private Row getFirstRow() { int init_row = this.init_row; if (start != null) { init_row--; } while (rows.size() <= init_row) { rows.add(new Row()); } return rows.get(init_row); } private Row getLastRow() { int max_row = this.max_row; if (stop != null) { max_row--; } while (rows.size() <= max_row) { rows.add(new Row()); } return rows.get(max_row); } private void inc_row() { current_row++; if (current_row > max_row) { max_row++; if (parent != null) { parent.inc_row(); } } } public void setStartElement(StartElement e) { getFirstRow().exchangeElementOrInsert(start, e); if (start == null) { current_row++; init_row++; max_row++; if (parent != null) { parent.inc_row(); } } start = e; } public void setStopElement(StopElement e) { getLastRow().exchangeElementOrInsert(stop, e); if (stop == null) { max_row++; if (parent != null) { parent.inc_row(); } } stop = e; } public void addColumn() { columns.add(new Column(getGraphics())); current_row = init_row; } public void addElement(Element e) { columns.get(columns.size() - 1).addElement(e); getNextRow().addElement(e); inc_row(); } @Override public boolean arrowIn() { if (start == null) { return false; } else { return start.arrowIn(); } } @Override public boolean connectIn() { for (Column c : columns) { if (c.getFirstElement().connectIn()) { return true; } } return false; } @Override public boolean connectOut_overrideable() { for (Column c : columns) { if (c.getLastElement().connectOut()) { return true; } } return false; } @Override protected Point getConnect(Direction dir) { if (dir.equals(Direction.UP)) { if (start != null) { return start.getConnect(dir); } } if (dir.equals(Direction.DOWN)) { if (stop != null) { return stop.getConnect(dir); } } return super.getConnect(dir); } @Override protected int getHeight() { int height = 0; for (Column c : columns) { int h = c.getHeight(); if (h > height) { height = h; } } if (start != null) { height += start.getHeight(); } if (stop != null) { height += stop.getHeight(); } return height; } @Override public int getLeftWidth() { int width = 0, i = 0; for (i = 0; i < columns.size() / 2; i++) { width += columns.get(i).getWidth(); } if (columns.size() % 2 == 1) { width += columns.get(i).getLeftWidth(); } width += (columns.size() - 1) / 2.0 * (Const.COLUMN_PAD * getZoom()); if (start != null) { if (start.getLeftWidth() > width) { width = start.getLeftWidth(); } } if (stop != null) { if (stop.getLeftWidth() > width) { width = stop.getLeftWidth(); } } return width; } @Override protected int getRightWidth() { int width = 0, i = columns.size() / 2; if (columns.size() % 2 == 1) { width += columns.get(i).getRightWidth(); i++; } for (; i < columns.size(); i++) { width += columns.get(i).getWidth(); } width += (columns.size() - 1) / 2.0 * (Const.COLUMN_PAD * getZoom()); if (start != null) { if (start.getRightWidth() > width) { width = start.getRightWidth(); } } if (stop != null) { if (stop.getRightWidth() > width) { width = stop.getRightWidth(); } } return width; } @Override public int getWidth() { int width = 0, i = 0; for (i = 0; i < columns.size(); i++) { width += columns.get(i).getWidth(); } width += (columns.size() - 1) * (Const.COLUMN_PAD * getZoom()); if (start != null) { if (start.getWidth() > width) { width = start.getWidth(); } } if (stop != null) { if (stop.getWidth() > width) { width = stop.getWidth(); } } return width; } @Override public void setX(int x) { if (start != null) { start.setX(x); } if (stop != null) { stop.setX(x); } if (columns.size() == 1) { columns.get(0).setX(x); } else { x -= getLeftWidth(); int i = 1; for (Column c : columns) { x += c.getLeftWidth(); c.setX(x); x += c.getRightWidth(); if (i < columns.size()) { x += Const.COLUMN_PAD * getZoom(); } i++; } } } protected StartElement getStartElement() { return start; } protected StopElement getStopElement() { return stop; } public void removeEmptyColumns() { // remove empty columns first (may be possible because of goto element for (int i = 0; i < columns.size();) { if (columns.get(i).isEmpty()) { columns.remove(i); } else { i++; } } } @Override public void paint() { boolean paintstart = connectIn(); boolean paintstop = connectOut(); if (start == null) { paintstart = false; } if (stop == null) { paintstop = false; } if (paintstart) { start.paint(); } if (paintstop) { stop.paint(); } for (Column c : columns) { if (paintstart) { start.connectTo(c.getFirstElement()); } c.paint(); if (paintstop) { stop.connectTo(c.getLastElement()); } } } @Override public void printData(String prefix) { prefix += " "; for (Column c : columns) { c.printData(prefix + "\n"); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/AEnd.java0000644000175000017500000000137412533641120025310 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.diagram.DiagramHandler; public class AEnd extends End { public AEnd(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, id == null ? "AEnd" : id); } @Override public void paint() { Point cord = getPosition(); getGraphics().drawArc(cord.x - (int) (10 * getZoom()), cord.y - (int) (10 * getZoom()), (int) (21 * getZoom()), (int) (21 * getZoom()), 0, 360); int delta = (int) (21 * getZoom() / 2 / Math.sqrt(2)); getGraphics().drawLine(cord.x - delta, cord.y - delta, cord.x + delta, cord.y + delta); getGraphics().drawLine(cord.x - delta, cord.y + delta, cord.x + delta, cord.y - delta); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/WhileElement.java0000644000175000017500000000233212533641120027056 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public abstract class WhileElement extends Element { public WhileElement(DiagramHandler handler, Graphics2D g, int padding, String id) { super(handler, g, padding, id); } public void connectTo(StartElement start, StopElement stop) { if (connectOut() && start.connectIn()) { Point from = getConnect(Direction.UP); Point to = start.getConnect(Direction.LEFT); getGraphics().drawLine(from.x, from.y, from.x, to.y); if (arrowOut() && start.arrowIn()) { Connector.drawArrow(getGraphics(), getZoom(), from.x, to.y, to.x, to.y); } else { getGraphics().drawLine(from.x, to.y, to.x, to.y); } } if (connectIn() && stop.connectOut()) { Point to = getConnect(Direction.DOWN); Point from = stop.getConnect(Direction.LEFT); getGraphics().drawLine(from.x, from.y, to.x, from.y); if (arrowIn() && stop.arrowOut()) { Connector.drawArrow(getGraphics(), getZoom(), to.x, from.y, to.x, to.y); } else { getGraphics().drawLine(to.x, from.y, to.x, to.y); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Column.java0000644000175000017500000000325412533641120025735 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.util.ArrayList; public class Column { private ArrayList elements; private Graphics2D graphics; public Column(Graphics2D graphics) { elements = new ArrayList(); this.graphics = graphics; } public boolean isEmpty() { return elements.isEmpty(); } public Element getFirstElement() { if (!elements.isEmpty()) { return elements.get(0); } return null; } public Element getLastElement() { if (!elements.isEmpty()) { return elements.get(elements.size() - 1); } return null; } public void addElement(Element e) { elements.add(e); } public int getHeight() { int height = 0; for (Element e : elements) { height += e.getHeight() + e.getPadding() * 2; } return height; } public int getLeftWidth() { int width = 0; for (Element e : elements) { int w = e.getLeftWidth(); if (w > width) { width = w; } } return width; } public int getRightWidth() { int width = 0; for (Element e : elements) { int w = e.getRightWidth(); if (w > width) { width = w; } } return width; } public int getWidth() { return getLeftWidth() + getRightWidth(); } public void setX(int x) { for (Element e : elements) { e.setX(x); } } public void paint() { Element current = null; for (Element e : elements) { if (current != null) { new Connector(graphics, current, e).paint(); } e.paint(); current = e; } } public void printData(String prefix) { for (Element e : elements) { e.printData(prefix); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Element.java0000644000175000017500000000612412533641120026070 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public abstract class Element { private Graphics2D graphics; private int leftwidth, rightwidth, height; private int padding; private Point cord; private String id; private Row row; private DiagramHandler handler; private float zoom; // specifies whether the element must not connect to another element. private boolean terminated; public Element(DiagramHandler handler, Graphics2D g, int padding, String id) { this.handler = handler; graphics = g; this.padding = padding; this.id = id; leftwidth = 0; rightwidth = 0; height = 0; cord = new Point(0, 0); zoom = handler.getZoomFactor(); } public void setRow(Row row) { this.row = row; } public Row getRow() { return row; } public final void setTerminated() { terminated = true; } public final void setNotTerminated() { terminated = false; } public Point getPosition() { return cord; } public void setY(int y) { cord.y = y; } public void setX(int x) { cord.x = x; } protected Graphics2D getGraphics() { return graphics; } public String getId() { return id; } protected int getHeight() { return height; } protected void setHeight(int height) { this.height = height; } protected int getLeftWidth() { return leftwidth; } protected int getRightWidth() { return rightwidth; } protected int getWidth() { return getLeftWidth() + getRightWidth(); } protected void setWidth(int width) { setLeftWidth(width / 2); setRightWidth(width - width / 2); } protected void setLeftWidth(int width) { leftwidth = width; } protected void setRightWidth(int width) { rightwidth = width; } protected int getPadding() { return padding; } public abstract void paint(); public boolean connectIn() { return true; } public boolean connectOut_overrideable() { return true; } public final boolean connectOut() { return connectOut_overrideable() && !terminated; } public boolean arrowOut() { return true; } public boolean arrowIn() { return true; } public void printData(String prefix) { System.out.println(prefix + this.getClass().getSimpleName()); } // get connect for GOTO element protected Point getNonStdConnectIn(Direction dir) { return getConnect(dir); } protected Point getNonStdConnectOut(Direction dir) { return getConnect(dir); } protected Point getConnect(Direction dir) { Point c = (Point) cord.clone(); if (dir == Direction.UP) { c.y -= getHeight() / 2; } else if (dir == Direction.DOWN) { c.y += getHeight() - getHeight() / 2; } else if (dir == Direction.LEFT) { c.x -= getLeftWidth(); } else if (dir == Direction.RIGHT) { c.x += getRightWidth(); } return c; } protected DiagramHandler getHandler() { return handler; } protected float getZoom() { return zoom; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Const.java0000644000175000017500000000105012533641120025556 0ustar benbenpackage com.baselet.element.old.activity; public class Const { // vertical pad between elements public static final int PAD = 10; // horizontal pad between columns public static final int COLUMN_PAD = 30; // seperation of goto elements public static final int GOTO_SEP = 4; // left/right pad for diagram border public static final int DIAGRAM_PAD = 30; // minwidth/height of the diagram public static final int MIN_WIDTH = 50; public static final int MIN_HEIGHT = 50; public static final boolean DEBUG = false; } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/Activity.java0000644000175000017500000000240712533641120026273 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import com.baselet.diagram.DiagramHandler; public class Activity extends Element { protected Label label; public Activity(DiagramHandler handler, String label, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), id == null ? label : id); this.label = new Label(handler, label, g, (int) (5 * getZoom())); } @Override protected int getHeight() { return label.getHeight() + label.getPadding() * 2 + super.getHeight(); } @Override protected int getLeftWidth() { return label.getLeftWidth() + label.getPadding() + super.getLeftWidth(); } @Override protected int getRightWidth() { return label.getRightWidth() + label.getPadding() + super.getRightWidth(); } @Override public void setY(int y) { super.setY(y); label.setY(y); } @Override public void setX(int x) { super.setX(x); label.setX(x); } @Override public void paint() { int h = getHeight(); label.paint(); getGraphics().drawRoundRect(getPosition().x - label.getLeftWidth() - label.getPadding(), getPosition().y - h / 2, label.getWidth() + label.getPadding() * 2, h, (int) (20 * getZoom()), (int) (20 * getZoom())); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/StartElement.java0000644000175000017500000000226612533641120027111 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import java.awt.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.DiagramHandler; public class StartElement extends Element { public StartElement(DiagramHandler handler, Graphics2D g, int padding, String id) { super(handler, g, padding, id); } @Override public void paint() { } @Override public boolean arrowIn() { return false; } public void connectTo(Element e) { if (e != null) { if (connectOut_overrideable() && e.connectIn()) { Point from = getPosition(); Point to = e.getConnect(Direction.UP); if (from.x == to.x) { from = getConnect(Direction.DOWN); } else if (from.x < to.x) { from = getConnect(Direction.RIGHT); } else if (from.x > to.x) { from = getConnect(Direction.LEFT); } if (from.x != to.x) { getGraphics().drawLine(from.x, from.y, to.x, from.y); } if (arrowOut() && e.arrowIn()) { Connector.drawArrow(getGraphics(), getZoom(), to.x, from.y, to.x, to.y); } else { getGraphics().drawLine(to.x, from.y, to.x, to.y); } } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/activity/EndIf.java0000644000175000017500000000150512533641120025462 0ustar benbenpackage com.baselet.element.old.activity; import java.awt.Graphics2D; import com.baselet.diagram.DiagramHandler; public class EndIf extends StopElement { private int h = (int) (40 * getZoom()); private int w = (int) (40 * getZoom()); public EndIf(DiagramHandler handler, Graphics2D g, String id) { super(handler, g, (int) (Const.PAD * handler.getZoomFactor()), id == null ? "EndIf" : id); setHeight(h); setWidth(w); } @Override public void paint() { int x = getPosition().x; int y = getPosition().y; getGraphics().drawLine(x, y - h / 2, x + w / 2, y); getGraphics().drawLine(x, y - h / 2, x - w / 2, y); getGraphics().drawLine(x, y + h / 2, x + w / 2, y); getGraphics().drawLine(x, y + h / 2, x - w / 2, y); } @Override public boolean arrowIn() { return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/old/OldGridElement.java0000644000175000017500000004642212533641120025506 0ustar benbenpackage com.baselet.element.old; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Stroke; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import javax.swing.JComponent; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.SharedUtils; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Line; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.Constants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.enums.Direction; import com.baselet.control.enums.ElementId; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; import com.baselet.element.ElementUtils; import com.baselet.element.UndoHistory; import com.baselet.element.UndoInformation; import com.baselet.element.facet.KeyValueFacet; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.element.interfaces.GridElementDeprecatedAddons; import com.baselet.element.sticking.PointChange; import com.baselet.element.sticking.Stickable; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.Stickables; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.AutocompletionText; public abstract class OldGridElement extends JComponent implements GridElement, com.baselet.element.interfaces.Component { private static final long serialVersionUID = 1L; protected static final Logger log = Logger.getLogger(OldGridElement.class); public static final float ALPHA_MIDDLE_TRANSPARENCY = 0.5f; public static final float ALPHA_FULL_TRANSPARENCY = 0.0f; private boolean enabled; private boolean autoresizeandmanualresizeenabled; private List panelAttributes = new ArrayList(); // deselectedColor and fgColor must be stored separately because selection changes the actual fgColor but not the fgColorBase /** * contains the value of the fgColor of the element if not selected */ protected Color fgColorBase = Converter.convert(ColorOwn.BLACK); /** * contains the current fgColor of the element. Will be overwritten by selectioncolor if it's selected */ protected Color fgColor = fgColorBase; private String fgColorString = ""; protected Color bgColor = Converter.convert(ColorOwn.WHITE); private String bgColorString = ""; protected float alphaFactor; protected final UndoHistory undoStack = new UndoHistory(); public OldGridElement() { this.setSize(100, 100); setVisible(true); enabled = true; autoresizeandmanualresizeenabled = false; } @Override public void setEnabled(boolean en) { super.setEnabled(en); if (!en && enabled) { removeMouseListener(Main.getHandlerForElement(this).getEntityListener(this)); removeMouseMotionListener(Main.getHandlerForElement(this).getEntityListener(this)); enabled = false; } else if (en && !enabled) { addMouseListener(Main.getHandlerForElement(this).getEntityListener(this)); addMouseMotionListener(Main.getHandlerForElement(this).getEntityListener(this)); enabled = true; } } public boolean isManualResized() { autoresizeandmanualresizeenabled = true; return isManResized(); } private boolean isManResized() { Vector lines = Utils.decomposeStringsWithComments(getPanelAttributes()); for (String line : lines) { if (line.startsWith("autoresize=false")) { return true; } } return false; } protected boolean isAutoResizeandManualResizeEnabled() { return autoresizeandmanualresizeenabled; } public void setManualResized() { if (autoresizeandmanualresizeenabled) { if (!isManResized()) { setPanelAttributes(getPanelAttributes() + Constants.NEWLINE + "autoresize=false"); if (equals(Main.getInstance().getEditedGridElement())) { Main.getInstance().setPropertyPanelToGridElement(this); } } } } // Some GridElements need additionalAttributes to be displayed correctly (eg: Relations need exact positions for edges) @Override public String getAdditionalAttributes() { return ""; } @Override public void setAdditionalAttributes(String s) {} @Override public String getPanelAttributes() { return SharedUtils.listToString("\n", panelAttributes); } @Override public List getPanelAttributesAsList() { return panelAttributes; } @Override public void setPanelAttributes(String panelAttributes) { this.panelAttributes = Arrays.asList(panelAttributes.split("\n", -1)); // split with -1 to retain empty lines at the end } @Override public String getSetting(String key) { for (String line : getPanelAttributesAsList()) { if (line.startsWith(key + KeyValueFacet.SEP)) { String[] split = line.split(KeyValueFacet.SEP, 2); if (split.length > 1) { return split[1]; } } } return null; } @Override public void setProperty(String key, Object newValue) { StringBuilder sb = new StringBuilder(""); for (String line : panelAttributes) { if (!line.startsWith(key.toString())) { sb.append(line).append("\n"); } } if (sb.length() > 0) { sb.setLength(sb.length() - 1); // remove last linebreak } if (newValue != null && !newValue.toString().isEmpty()) { sb.append("\n").append(key.toString()).append("=").append(newValue); // null will not be added as a value } setPanelAttributes(sb.toString()); } public Composite[] colorize(Graphics2D g2) { bgColorString = ""; fgColorString = ""; bgColor = getDefaultBackgroundColor(); fgColorBase = Converter.convert(ColorOwn.DEFAULT_FOREGROUND); List v = panelAttributes; for (int i = 0; i < v.size(); i++) { String line = v.get(i); if (line.indexOf("bg=") >= 0) { bgColorString = line.substring("bg=".length()); // OldGridElements apply transparency for background explicitly, therefore don't apply it here bgColor = Converter.convert(ColorOwn.forStringOrNull(bgColorString, Transparency.FOREGROUND)); if (bgColor == null) { bgColor = getDefaultBackgroundColor(); } } else if (line.indexOf("fg=") >= 0) { fgColorString = line.substring("fg=".length()); fgColorBase = Converter.convert(ColorOwn.forStringOrNull(fgColorString, Transparency.FOREGROUND)); if (fgColorBase == null) { fgColorBase = Converter.convert(ColorOwn.DEFAULT_FOREGROUND); } if (!Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this)) { fgColor = fgColorBase; } } } alphaFactor = ALPHA_MIDDLE_TRANSPARENCY; if (bgColorString.equals("") || bgColorString.equals("default")) { alphaFactor = ALPHA_FULL_TRANSPARENCY; } Composite old = g2.getComposite(); AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaFactor); Composite[] composites = { old, alpha }; return composites; } protected Color getDefaultBackgroundColor() { return Converter.convert(ColorOwn.DEFAULT_BACKGROUND); } @Override public Dimension getRealSize() { return new Dimension(getRectangle().width / Main.getHandlerForElement(this).getGridSize() * Constants.DEFAULTGRIDSIZE, getRectangle().height / Main.getHandlerForElement(this).getGridSize() * Constants.DEFAULTGRIDSIZE); } @Override public Set getResizeArea(int x, int y) { Set returnSet = new HashSet(); if (x <= 5 && x >= 0) { returnSet.add(Direction.LEFT); } else if (x <= getRectangle().width && x >= getRectangle().width - 5) { returnSet.add(Direction.RIGHT); } if (y <= 5 && y >= 0) { returnSet.add(Direction.UP); } else if (y <= getRectangle().height && y >= getRectangle().height - 5) { returnSet.add(Direction.DOWN); } return returnSet; } @Override public void setLocationDifference(int diffx, int diffy) { this.setLocation(getRectangle().x + diffx, getRectangle().y + diffy); } /** * Must be overwritten because Swing uses this method to tell if 2 elements are overlapping * It's also used to determine which element gets selected if there are overlapping elements (the smallest one) * IMPORTANT: on overlapping elements, contains is called for all elements until the first one returns true, then the others contain methods are not called */ @Override public boolean contains(java.awt.Point p) { return this.contains(p.x, p.y); } /** * Must be overwritten because Swing sometimes uses this method instead of contains(Point) */ @Override public boolean contains(int x, int y) { return ElementUtils.checkForOverlap(this, new Point(x, y)); } @Override public boolean isInRange(Rectangle rect1) { return rect1.contains(getRectangle()); } public void setInProgress(Graphics g, boolean flag) { if (flag) { Graphics2D g2 = (Graphics2D) g; g2.setFont(Main.getHandlerForElement(this).getFontHandler().getFont()); g2.setColor(Color.red); Main.getHandlerForElement(this).getFontHandler().writeText(g2, "in progress...", getRectangle().width / 2 - 40, getRectangle().height / 2 + (int) Main.getHandlerForElement(this).getFontHandler().getFontSize() / 2, AlignHorizontal.LEFT); } else { repaint(); } } public GridElement cloneFromMe() { try { java.lang.Class cx = this.getClass(); // get class of dynamic object GridElement c = cx.newInstance(); c.setPanelAttributes(getPanelAttributes()); // copy states c.setRectangle(getRectangle()); Main.getHandlerForElement(this).setHandlerAndInitListeners(c); return c; } catch (Exception e) { log.error("Error at calling CloneFromMe() on entity", e); } return null; } @Override public StickingPolygon generateStickingBorder(Rectangle rect) { return generateStickingBorder(rect.x, rect.y, rect.width, rect.height); } public StickingPolygon generateStickingBorder(int x, int y, int width, int height) { StickingPolygon p = new StickingPolygon(x, y); p.addRectangle(0, 0, width, height); return p; } public final void drawStickingPolygon(Graphics2D g2) { Rectangle rect = new Rectangle(0, 0, getRectangle().width - 1, getRectangle().height - 1); StickingPolygon poly = this.generateStickingBorder(rect); if (poly != null) { Color c = g2.getColor(); Stroke s = g2.getStroke(); g2.setColor(Converter.convert(ColorOwn.SELECTION_FG)); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); for (Line line : poly.getStickLines()) { g2.drawLine(line.getStart().getX().intValue(), line.getStart().getY().intValue(), line.getEnd().getX().intValue(), line.getEnd().getY().intValue()); } g2.setColor(c); g2.setStroke(s); } } private boolean translateForExport = false; public void translateForExport() { translateForExport = true; } public boolean isDeprecated() { return true; } @Override public final void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; if (translateForExport) { g2.translate(Constants.EXPORT_DISPLACEMENT, Constants.EXPORT_DISPLACEMENT); } boolean selected = Main.getHandlerForElement(this).getDrawPanel().getSelector().isSelected(this); if (selected) { if (isDeprecated()) { Color oldColor = g2.getColor(); g2.setColor(Converter.convert(ColorOwn.RED.transparency(Transparency.SELECTION_BACKGROUND))); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setColor(oldColor); } fgColor = Converter.convert(ColorOwn.SELECTION_FG); if (SharedConfig.getInstance().isShow_stickingpolygon()) { drawStickingPolygon(g2); } } else { fgColor = fgColorBase; } updateModelFromText(); paintEntity(g2); } public abstract void paintEntity(Graphics g); @Override public com.baselet.element.interfaces.Component getComponent() { return this; } @Override public List getAutocompletionList() { return new ArrayList(); } @Override public void updateModelFromText() { /* OldGridElement has no model but simply parses the properties text within every paint() call */ } @Override public Integer getLayer() { return getLayerHelper(LayerFacet.DEFAULT_VALUE); } protected Integer getLayerHelper(Integer defaultLayer) { try { return Integer.valueOf(getSettingHelper(LayerFacet.KEY, defaultLayer.toString())); } catch (NumberFormatException e) {/* default value applies */} return defaultLayer; } private String getSettingHelper(String key, String defaultValue) { key = key + KeyValueFacet.SEP; for (String s : panelAttributes) { if (s.startsWith(key)) { String[] value = s.split(key); if (value.length == 0) { return ""; } return value[1]; } } return defaultValue; } @Override public Integer getGroup() { try { return Integer.valueOf(getSettingHelper(GroupFacet.KEY, null)); } catch (NumberFormatException e) {/* default value applies */} return null; } @Override public Rectangle getRectangle() { return Converter.convert(getBounds()); } @Override public void setRectangle(Rectangle rect) { setBounds(rect.x, rect.y, rect.width, rect.height); } @Override public void setBoundsRect(Rectangle rect) { setBounds(Converter.convert(rect)); } @Override public Rectangle getBoundsRect() { return Converter.convert(getBounds()); } @Override public void repaintComponent() { this.repaint(); } @Override public DrawHandler getDrawHandler() { return null; } @Override public DrawHandler getMetaDrawHandler() { return null; } @Override public ElementId getId() { return null; } @Override public void drag(Collection resizeDirection, int diffX, int diffY, Point mousePosBeforeDrag, boolean isShiftKeyDown, boolean firstDrag, StickableMap stickables, boolean undoable) { Rectangle oldRect = getRectangle(); StickingPolygon stickingPolygonBeforeLocationChange = generateStickingBorder(); String oldAddAttr = getAdditionalAttributes(); if (resizeDirection.isEmpty()) { // Move GridElement setLocationDifference(diffX, diffY); } else { // Resize GridElement Rectangle rect = getRectangle(); if (isShiftKeyDown && diagonalResize(resizeDirection)) { // Proportional Resize boolean mouseToRight = diffX > 0 && diffX > diffY; boolean mouseDown = diffY > 0 && diffY > diffX; boolean mouseLeft = diffX < 0 && diffX < diffY; boolean mouseUp = diffY < 0 && diffY < diffX; if (mouseToRight || mouseLeft) { diffY = diffX; } if (mouseDown || mouseUp) { diffX = diffY; } } if (resizeDirection.contains(Direction.LEFT) && resizeDirection.contains(Direction.RIGHT)) { rect.setX(rect.getX() - diffX / 2); rect.setWidth(Math.max(rect.getWidth() + diffX, minSize())); } else if (resizeDirection.contains(Direction.LEFT)) { int newWidth = rect.getWidth() - diffX; if (newWidth >= minSize()) { rect.setX(rect.getX() + diffX); rect.setWidth(newWidth); } } else if (resizeDirection.contains(Direction.RIGHT)) { rect.setWidth(Math.max(rect.getWidth() + diffX, minSize())); } if (resizeDirection.contains(Direction.UP)) { int newHeight = rect.getHeight() - diffY; if (newHeight >= minSize()) { rect.setY(rect.getY() + diffY); rect.setHeight(newHeight); } } if (resizeDirection.contains(Direction.DOWN)) { rect.setHeight(Math.max(rect.getHeight() + diffY, minSize())); } setRectangle(rect); updateModelFromText(); } moveStickables(stickables, undoable, oldRect, stickingPolygonBeforeLocationChange, oldAddAttr); } private void moveStickables(StickableMap stickables, boolean undoable, Rectangle oldRect, StickingPolygon stickingPolygonBeforeLocationChange, String oldAddAttr) { Map> stickableChanges = Stickables.moveStickPointsBasedOnPolygonChanges(stickingPolygonBeforeLocationChange, generateStickingBorder(), stickables, getGridSize()); if (undoable) { undoStack.add(new UndoInformation(getRectangle(), oldRect, stickableChanges, getGridSize(), oldAddAttr, getAdditionalAttributes())); } } public int getGridSize() { return Main.getHandlerForElement(this).getGridSize(); } @Override public void afterModelUpdate() {} @Override public boolean isSelectableOn(Point point) { return getRectangle().contains(point); } private boolean diagonalResize(Collection resizeDirection) { return resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.RIGHT) || resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.LEFT) || resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.LEFT) || resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.RIGHT); } @Override public void dragEnd() { // only used by some specific elements like Relations } @Override public void setRectangleDifference(int diffx, int diffy, int diffw, int diffh, boolean firstDrag, StickableMap stickables, boolean undoable) { Rectangle oldRect = getRectangle(); StickingPolygon stickingPolygonBeforeLocationChange = generateStickingBorder(); String oldAddAttr = getAdditionalAttributes(); setRectangle(new Rectangle(oldRect.x + diffx, oldRect.y + diffy, oldRect.getWidth() + diffw, oldRect.getHeight() + diffh)); moveStickables(stickables, undoable, oldRect, stickingPolygonBeforeLocationChange, oldAddAttr); } @Override public StickingPolygon generateStickingBorder() { return generateStickingBorder(getRectangle()); } private int minSize() { return Main.getHandlerForElement(this).getGridSize() * 2; } @Override public void undoDrag() { execUndoInformation(true); } private void execUndoInformation(boolean undo) { UndoInformation undoInfo = undoStack.get(undo); if (undoInfo != null) { setRectangle(getRectangle().add(undoInfo.getDiffRectangle(getGridSize(), undo))); Stickables.applyChanges(undoInfo.getStickableMoves(undo), null); // setAdditionalAttributes(undoInfo.getAdditionalAttributes(undo)); //Issue 217: of all OldGridElements only the Relation uses additional attributes and in that case they must not be set because of zooming errors (see Issue 217) } } @Override public void redoDrag() { execUndoInformation(false); } @Override public void mergeUndoDrag() { UndoInformation undoInfoA = undoStack.remove(); UndoInformation undoInfoB = undoStack.remove(); undoStack.add(undoInfoA.merge(undoInfoB)); } @Override public GridElementDeprecatedAddons getDeprecatedAddons() { return GridElementDeprecatedAddons.NONE; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/ElementUtils.java0000644000175000017500000000742012533641120024477 0ustar benbenpackage com.baselet.element; import java.util.List; import javax.swing.JComponent; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; import com.baselet.element.relation.Relation; public class ElementUtils { /** * Must be overwritten because Swing uses this method to tell if 2 elements are overlapping * It's also used to determine which element gets selected if there are overlapping elements (the smallest one) * IMPORTANT: on overlapping elements, contains is called for all elements until the first one returns true, then the others contain methods are not called * * In future this logic should be the same as in BaseletGWT.DrawPanel.getGridElementOnPosition() which is much simpler because its externally calculated * (this migration is only possible if there are not GridElement Listeners, but instead only one Diagram Listener which delegates the event to the specific GridElement like in GWT) */ public static boolean checkForOverlap(GridElement gridElement, Point p) { JComponent component = (JComponent) gridElement.getComponent(); java.awt.Rectangle rectangle = component.getVisibleRect(); Point absolute = new Point(gridElement.getRectangle().getX() + p.getX(), gridElement.getRectangle().getY() + p.getY()); if (!rectangle.contains(p.x, p.y)) { return false; } DrawPanel drawPanel = Main.getHandlerForElement(gridElement).getDrawPanel(); List elements = drawPanel.getGridElements(); Selector selector = drawPanel.getSelector(); for (GridElement other : elements) { if (other == gridElement || other.getLayer() < gridElement.getLayer() || !other.isSelectableOn(absolute)) { continue; // ignore this element, elements with a lower layer and elements which are not selectable on the point } // issue #260: if a relation is the only selected element its selection should be retained if (gridElement instanceof Relation && other instanceof Relation) { if (selector.isSelectedOnly(gridElement)) { return true; } if (selector.isSelectedOnly(other)) { return false; } } JComponent otherComponent = (JComponent) other.getComponent(); if (other.getLayer() > gridElement.getLayer()) { // elements with higher layer can "overwrite" contains-value of this // move point to coordinate system of other entity Point other_p = new Point(p.x + gridElement.getRectangle().x - other.getRectangle().x, p.y + gridElement.getRectangle().y - other.getRectangle().y); if (otherComponent.contains(Converter.convert(other_p))) { return false; } } java.awt.Rectangle other_rectangle = otherComponent.getVisibleRect(); // move bounds to coordinate system of this component other_rectangle.x += other.getRectangle().x - gridElement.getRectangle().x; other_rectangle.y += other.getRectangle().y - gridElement.getRectangle().y; // when elements intersect, select the smaller element except if it is an old relation (because they have a larger rectangle than they use). NOTE: Old Relations are not checked because they do not properly implement isSelectableOn if (!(other instanceof com.baselet.element.old.element.Relation) && rectangle.intersects(other_rectangle) && firstSmallerThanSecond(other_rectangle, rectangle)) { return false; } } return true; } private static boolean firstSmallerThanSecond(java.awt.Rectangle first, java.awt.Rectangle second) { int areaFirst = first.getSize().height * first.getSize().width; int areaSecond = second.getSize().height * second.getSize().width; if (areaFirst < areaSecond) { return true; } return false; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/element/ComponentSwing.java0000644000175000017500000000605512533641120025042 0ustar benbenpackage com.baselet.element; import java.awt.Graphics; import javax.swing.JComponent; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.swing.DrawHandlerSwing; import com.baselet.element.interfaces.Component; public class ComponentSwing extends JComponent implements Component { private static final long serialVersionUID = 1L; private final DrawHandlerSwing drawer; private final DrawHandlerSwing metaDrawer; private final NewGridElement gridElement; public ComponentSwing(NewGridElement gridElement) { this.gridElement = gridElement; drawer = new DrawHandlerSwing(gridElement); metaDrawer = new DrawHandlerSwing(gridElement); } @Override public void paint(Graphics g) { drawer.setGraphics(g); metaDrawer.setGraphics(g); boolean selected = Main.getHandlerForElement(gridElement).getDrawPanel().getSelector().isSelected(gridElement); drawer.drawAll(selected); if (selected) { metaDrawer.drawAll(); } } public void translateForExport() { drawer.setTranslate(true); metaDrawer.setTranslate(true); } @Override public DrawHandler getDrawHandler() { return drawer; } @Override public DrawHandler getMetaDrawHandler() { return metaDrawer; } /** * Must be overwritten because Swing uses this method to tell if 2 elements are overlapping * It's also used to determine which element gets selected if there are overlapping elements (the smallest one) * IMPORTANT: on overlapping elements, contains is called for all elements until the first one returns true, then the others contain methods are not called */ @Override public boolean contains(java.awt.Point p) { return this.contains(p.x, p.y); } /** * Must be overwritten because Swing sometimes uses this method instead of contains(Point) */ @Override public boolean contains(int x, int y) { Rectangle r = gridElement.getRectangle(); // only check if element selectable on the position, because some elements are not everywhere selectable (eg: Relation) if (gridElement.isSelectableOn(new Point(r.getX() + x, r.getY() + y))) { return ElementUtils.checkForOverlap(gridElement, new Point(x, y)); } else { return false; } } @Override public Rectangle getBoundsRect() { return Converter.convert(getBounds()); } @Override public void repaintComponent() { this.repaint(); } @Override public void setBoundsRect(Rectangle rect) { this.setBounds(rect.x, rect.y, rect.width, rect.height); } @Override public void afterModelUpdate() { repaint(); // necessary e.g. for NewGridElement Relation to make sure it gets redrawn correctly when a sticking element is moved around } public void setHandler(DiagramHandler diagramHandler) { drawer.setHandler(diagramHandler); metaDrawer.setHandler(diagramHandler); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/0000755000175000017500000000000012533641120021064 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/MainPlugin.java0000644000175000017500000000600412533641120023772 0ustar benbenpackage com.baselet.plugin; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Dictionary; import org.eclipse.core.runtime.FileLocator; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; import com.baselet.control.Main; import com.baselet.control.config.handler.ConfigHandler; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; import com.baselet.control.util.Path; import com.baselet.gui.CurrentGui; import com.baselet.plugin.gui.EclipseGUI; /** * The activator class controls the plug-in life cycle */ public class MainPlugin extends AbstractUIPlugin { // The plug-in ID private static String pluginId; public static String getPluginId() { return pluginId; } // The shared instance private static MainPlugin plugin; /** * The constructor */ public MainPlugin() { Program.getInstance().setRuntimeType(RuntimeType.ECLIPSE_PLUGIN); plugin = this; } /* (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ @Override public void start(BundleContext context) throws Exception { super.start(context); initHomeProgramPath(); Main.getInstance().initLogger(); readBundleManifestInfo(); ConfigHandler.loadConfig(); Main.getInstance().init(new EclipseGUI(Main.getInstance())); } private void initHomeProgramPath() throws IOException { String path = null; URL homeURL = MainPlugin.getURL(); path = FileLocator.toFileURL(homeURL).toString().substring("file:/".length()); if (File.separator.equals("/")) { path = "/" + path; } Path.setHomeProgram(path); } // Issue 83: Use OSGI Bundle to read Manifest information private void readBundleManifestInfo() { Dictionary headers = MainPlugin.getDefault().getBundle().getHeaders(); pluginId = MainPlugin.getDefault().getBundle().getSymbolicName(); Program.getInstance().init(headers.get(Constants.MANIFEST_BUNDLE_VERSION)); } /* (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ @Override public void stop(BundleContext context) throws Exception { CurrentGui.getInstance().getGui().closeWindow(); plugin = null; super.stop(context); } /** * Returns the shared instance * * @return the shared instance */ public static MainPlugin getDefault() { return plugin; } /** * Returns an image descriptor for the image file at the given * plug-in relative path * * @param path * the path * @return the image descriptor */ public static ImageDescriptor getImageDescriptor(String path) { return imageDescriptorFromPlugin(pluginId, path); } public static URL getURL() { return FileLocator.find(MainPlugin.getDefault().getBundle(), new org.eclipse.core.runtime.Path("/"), null); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/wizard/0000755000175000017500000000000012533641120022364 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/wizard/NewWizardPage.java0000644000175000017500000001402412533641120025737 0ustar benbenpackage com.baselet.plugin.wizard; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jface.dialogs.IDialogPage; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ContainerSelectionDialog; import com.baselet.control.enums.Program; /** * The "New" wizard page allows setting the container for the new file as well * as the file name. The page will only accept file name without the extension * OR with the extension that matches the expected one (uxf/pxf). */ public class NewWizardPage extends WizardPage { private Text containerText; private Text fileText; private final ISelection selection; /** * Constructor for SampleNewWizardPage. */ public NewWizardPage(ISelection selection) { super(Program.getInstance().getProgramName() + " wizard"); setTitle(Program.getInstance().getProgramName() + " diagram"); setDescription("This wizard creates a " + Program.getInstance().getProgramName() + " diagram."); this.selection = selection; } /** * @see IDialogPage#createControl(Composite) */ @Override public void createControl(Composite parent) { Composite container = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); container.setLayout(layout); layout.numColumns = 3; layout.verticalSpacing = 9; // Input for the container where the new diagram should be placed Label label = new Label(container, SWT.NULL); label.setText("&Container:"); containerText = new Text(container, SWT.BORDER | SWT.SINGLE); GridData gd = new GridData(GridData.FILL_HORIZONTAL); containerText.setLayoutData(gd); containerText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { dialogChanged(); } }); // button to choose the container Button button = new Button(container, SWT.PUSH); button.setText("Browse..."); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleBrowse(); } }); // name of the diagram label = new Label(container, SWT.NULL); label.setText("&Diagram name:"); fileText = new Text(container, SWT.BORDER | SWT.SINGLE); gd = new GridData(GridData.FILL_HORIZONTAL); fileText.setLayoutData(gd); fileText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { dialogChanged(); } }); initialize(); dialogChanged(); setControl(container); } /** * Tests if the current workbench selection is a suitable container to use. */ private void initialize() { if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { IStructuredSelection ssel = (IStructuredSelection) selection; if (ssel.size() > 1) { return; } Object obj = ssel.getFirstElement(); // try to find a resource for the selected object IResource resource = null; if (obj instanceof IResource) { resource = (IResource) obj; } else if (obj instanceof IJavaElement) { resource = ((IJavaElement) obj).getResource(); } if (resource != null) { // convert the resource to a container and // initalize the container text with it IContainer container = null; if (resource instanceof IContainer) { container = (IContainer) resource; } else { container = resource.getParent(); } containerText.setText(container.getFullPath().toString()); } } fileText.setText("new_diagram." + Program.getInstance().getExtension()); } /** * Uses the standard container selection dialog to choose the new value for * the container field. */ private void handleBrowse() { ContainerSelectionDialog dialog = new ContainerSelectionDialog( getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, "Select new file container"); if (dialog.open() == Window.OK) { Object[] result = dialog.getResult(); if (result.length == 1) { containerText.setText(((Path) result[0]).toString()); } } } /** * Ensures that both text fields are set. */ private void dialogChanged() { IResource container = ResourcesPlugin.getWorkspace().getRoot() .findMember(new Path(getContainerName())); String fileName = getFileName(); if (getContainerName().length() == 0) { updateStatus("File container must be specified"); return; } if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) { updateStatus("File container must exist"); return; } if (!container.isAccessible()) { updateStatus("Project must be writable"); return; } if (fileName.length() == 0) { updateStatus("File name must be specified"); return; } if (fileName.replace('\\', '/').indexOf('/', 1) > 0) { updateStatus("File name must be valid"); return; } int dotLoc = fileName.lastIndexOf('.'); if (dotLoc != -1) { String ext = fileName.substring(dotLoc + 1); if (!ext.equalsIgnoreCase(Program.getInstance().getExtension())) { updateStatus("File extension must be \"" + Program.getInstance().getExtension() + "\""); return; } } updateStatus(null); } private void updateStatus(String message) { setErrorMessage(message); setPageComplete(message == null); } public String getContainerName() { return containerText.getText(); } public String getFileName() { return fileText.getText(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/wizard/NewWizard.java0000644000175000017500000001270412533641120025145 0ustar benbenpackage com.baselet.plugin.wizard; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWizard; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import com.baselet.control.enums.Program; import com.baselet.plugin.MainPlugin; /** * This is a sample new wizard. Its role is to create a new file * resource in the provided container. If the container resource * (a folder or a project) is selected in the workspace * when the wizard is opened, it will accept it as the target * container. The wizard creates one file with the extension * "uxf/pxf". If a sample multi-page editor (also available * as a template) is registered for the same extension, it will * be able to open it. */ public class NewWizard extends Wizard implements INewWizard { private final Logger log = Logger.getLogger(NewWizard.class); private NewWizardPage page; private ISelection selection; /** * Constructor for SampleNewWizard. */ public NewWizard() { super(); setNeedsProgressMonitor(true); } /** * Adding the page to the wizard. */ @Override public void addPages() { page = new NewWizardPage(selection); addPage(page); } /** * This method is called when 'Finish' button is pressed in * the wizard. We will create an operation and run it * using wizard as execution context. */ @Override public boolean performFinish() { final String containerName = page.getContainerName(); String fn = page.getFileName(); int dotLoc = fn.lastIndexOf('.'); if (dotLoc == -1) { fn += "." + Program.getInstance().getExtension(); } final String fileName = fn; IRunnableWithProgress op = new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException { try { doFinish(containerName, fileName, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; try { getContainer().run(true, false, op); } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); MessageDialog.openError(getShell(), "Error", realException.getMessage()); return false; } return true; } /** * The worker method. It will find the container, create the * file if missing or just replace its contents, and open * the editor on the newly created file. */ private void doFinish(String containerName, String fileName, IProgressMonitor monitor) throws CoreException { // create a sample file monitor.beginTask("Creating " + fileName, 2); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource resource = root.findMember(new Path(containerName)); if (!resource.exists() || !(resource instanceof IContainer)) { throwCoreException("Container \"" + containerName + "\" does not exist."); } IContainer container = (IContainer) resource; final IFile file = container.getFile(new Path(fileName)); try { InputStream stream = openContentStream(); if (file.exists()) { file.setContents(stream, true, true, monitor); } else { file.create(stream, true, monitor); } stream.close(); } catch (IOException e) {/* ignore */} monitor.worked(1); monitor.setTaskName("Opening file for editing..."); getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { IDE.openEditor(page, file, true); } catch (PartInitException e) { log.error("Cannot open Editor", e); } } }); monitor.worked(1); } /** * We will initialize file contents with a sample text. */ private InputStream openContentStream() { String progName = Program.getInstance().getProgramName().toLowerCase(); String contents = "<" + progName + "_diagram>"; return new ByteArrayInputStream(contents.getBytes()); } private void throwCoreException(String message) throws CoreException { IStatus status = new Status(IStatus.ERROR, MainPlugin.getPluginId(), IStatus.OK, message, null); throw new CoreException(status); } /** * We will accept the selection in the workbench to see if * we can initialize from it. * * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection) */ @Override public void init(IWorkbench workbench, IStructuredSelection selection) { this.selection = selection; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/0000755000175000017500000000000012533641120021650 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/Editor.java0000644000175000017500000001766212533641120023755 0ustar benbenpackage com.baselet.plugin.gui; import java.awt.Cursor; import java.awt.Frame; import java.awt.Panel; import java.io.File; import java.util.UUID; import javax.swing.SwingUtilities; import javax.swing.text.JTextComponent; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; import com.baselet.control.Main; import com.baselet.control.enums.Program; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.diagram.PaletteHandler; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.CurrentGui; import com.baselet.gui.pane.OwnSyntaxPane; public class Editor extends EditorPart { private static final Logger log = Logger.getLogger(Editor.class); private DiagramHandler handler; private Panel embeddedPanel; private final EclipseGUIBuilder guiComponents = new EclipseGUIBuilder(); private final UUID uuid = UUID.randomUUID(); @Override public void doSave(IProgressMonitor monitor) { handler.doSave(); monitor.done(); } @Override public void doSaveAs() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { handler.doSaveAs(Program.getInstance().getExtension()); } }); } @Override public boolean isSaveAsAllowed() { return true; } File diagramFile; private Frame mainFrame; @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { log.info("Call editor.init() " + uuid.toString()); setSite(site); setInput(input); setPartName(input.getName()); diagramFile = getFile(input); try { // use invokeAndWait to make sure the initialization is finished before SWT proceeds SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { // initialize embedded panel here (and not in createPartControl) to avoid ugly scrollbars embeddedPanel = guiComponents.initEclipseGui(); } }); } catch (Exception e) { throw new PartInitException("Create DiagramHandler interrupted", e); } } private File getFile(IEditorInput input) throws PartInitException { if (input instanceof IFileEditorInput) { // Files opened from workspace return ((IFileEditorInput) input).getFile().getLocation().toFile(); } else if (input instanceof org.eclipse.ui.ide.FileStoreEditorInput) { // Files from outside of the workspace (eg: edit current palette) return new File(((org.eclipse.ui.ide.FileStoreEditorInput) input).getURI()); } else { throw new PartInitException("Editor input not supported."); } } @Override public boolean isDirty() { return handler.isChanged(); } @Override public void createPartControl(Composite parent) { getGui().setCurrentEditor(Editor.this); // must be done before initalization of DiagramHandler (eg: to set propertypanel text) handler = new DiagramHandler(diagramFile); getGui().registerEditorForDiagramHandler(Editor.this, handler); getGui().setCurrentDiagramHandler(handler); // must be also set here because onFocus is not always called (eg: tab is opened during eclipse startup) getGui().open(handler); log.info("Call editor.createPartControl() " + uuid.toString()); mainFrame = SWT_AWT.new_Frame(new Composite(parent, SWT.EMBEDDED)); mainFrame.add(embeddedPanel); } private EclipseGUI getGui() { return (EclipseGUI) CurrentGui.getInstance().getGui(); } @Override public void setFocus() { log.info("Call editor.setFocus() " + uuid.toString()); getGui().setCurrentEditor(this); getGui().setCurrentDiagramHandler(handler); if (handler != null) { handler.getDrawPanel().getSelector().updateSelectorInformation(); } Display.getDefault().syncExec(new Runnable() { @Override public void run() { /** * usually the palettes get lost after switching the editor (for unknown reasons but perhaps because the Main class is build for exactly one palette (like in standalone umlet) but here every tab has its own palette) * Therefore recreate them and also reselect the current palette and repaint every element with scrollbars (otherwise they have a visual error) */ if (guiComponents.getPalettePanel().getComponentCount() == 0) { for (PaletteHandler palette : Main.getInstance().getPalettes().values()) { guiComponents.getPalettePanel().add(palette.getDrawPanel().getScrollPane(), palette.getName()); palette.getDrawPanel().getScrollPane().invalidate(); } } showPalette(getSelectedPaletteName()); getGui().setValueOfZoomDisplay(handler.getGridSize()); guiComponents.getPropertyTextPane().invalidate(); } }); } public DrawPanel getDiagram() { if (handler == null) { return null; } return handler.getDrawPanel(); } @Override public void dispose() { super.dispose(); log.info("Call editor.dispose( )" + uuid.toString()); // AB: The eclipse plugin might hang sometimes if this section is not placed into an event queue, since swing or swt is not thread safe! SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (guiComponents.getMailPanel().isVisible()) { guiComponents.getMailPanel().closePanel(); } getGui().editorRemoved(Editor.this); } }); } public void setCursor(Cursor cursor) { embeddedPanel.setCursor(cursor); } public OwnSyntaxPane getPropertyPane() { return guiComponents.getPropertyTextPane(); } public JTextComponent getCustomPane() { return guiComponents.getCustomPanel().getTextPane(); } public void requestFocus() { embeddedPanel.requestFocus(); } public Frame getMainFrame() { return mainFrame; } public void dirtyChanged() { org.eclipse.swt.widgets.Display.getDefault().asyncExec(new Runnable() { @Override public void run() { firePropertyChange(IEditorPart.PROP_DIRTY); } }); } public void diagramNameChanged() { org.eclipse.swt.widgets.Display.getDefault().asyncExec(new Runnable() { @Override public void run() { firePropertyChange(IWorkbenchPart.PROP_TITLE); } }); } public CustomElementHandler getCustomElementHandler() { return guiComponents.getCustomHandler(); } public void setMailPanelEnabled(boolean enable) { guiComponents.setMailPanelEnabled(enable); } public boolean isMailPanelVisible() { return guiComponents.getMailPanel().isVisible(); } public String getSelectedPaletteName() { return guiComponents.getPaletteList().getSelectedItem().toString(); } public int getMainSplitLocation() { return guiComponents.getMainSplit().getDividerLocation(); } public int getRightSplitLocation() { return guiComponents.getRightSplit().getDividerLocation(); } public int getMailSplitLocation() { return guiComponents.getMailSplit().getDividerLocation(); } public void showPalette(final String paletteName) { guiComponents.setPaletteActive(paletteName); } public void setCustomPanelEnabled(boolean enable) { guiComponents.setCustomPanelEnabled(enable); setDrawPanelEnabled(!enable); } private void setDrawPanelEnabled(boolean enable) { handler.getDrawPanel().getScrollPane().setEnabled(enable); } public void focusPropertyPane() { guiComponents.getPropertyTextPane().getTextComponent().requestFocus(); } public void open(final DiagramHandler handler) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { guiComponents.setContent(handler.getDrawPanel().getScrollPane()); } }); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/EclipseGUIBuilder.java0000644000175000017500000000366412533641120025764 0ustar benbenpackage com.baselet.plugin.gui; import java.awt.BorderLayout; import java.awt.Panel; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import javax.swing.JPanel; import javax.swing.JScrollPane; import com.baselet.control.config.Config; import com.baselet.gui.BaseGUIBuilder; import com.baselet.gui.CurrentGui; import com.baselet.gui.listener.GUIListener; import com.baselet.plugin.gui.EclipseGUI.Pane; public class EclipseGUIBuilder extends BaseGUIBuilder { private final FocusListener eclipseCustomCodePaneListener = new FocusListener() { @Override public void focusGained(FocusEvent e) { ((EclipseGUI) CurrentGui.getInstance().getGui()).setPaneFocused(Pane.CUSTOMCODE); } @Override public void focusLost(FocusEvent e) { ((EclipseGUI) CurrentGui.getInstance().getGui()).setPaneFocused(Pane.DIAGRAM); } }; private final FocusListener eclipseTextPaneListener = new FocusListener() { @Override public void focusGained(FocusEvent e) { ((EclipseGUI) CurrentGui.getInstance().getGui()).setPaneFocused(Pane.PROPERTY); } @Override public void focusLost(FocusEvent e) { ((EclipseGUI) CurrentGui.getInstance().getGui()).setPaneFocused(Pane.DIAGRAM); } }; private final JPanel contentPlaceHolder = new JPanel(new BorderLayout()); public Panel initEclipseGui() { Panel embedded_panel = new Panel(); embedded_panel.setLayout(new BorderLayout()); embedded_panel.add(initBase(contentPlaceHolder, Config.getInstance().getMain_split_position())); embedded_panel.addKeyListener(new GUIListener()); getCustomHandler().getPanel().getTextPane().addFocusListener(eclipseCustomCodePaneListener); getPropertyTextPane().getTextComponent().addFocusListener(eclipseTextPaneListener); return embedded_panel; } public void setContent(JScrollPane scrollPane) { contentPlaceHolder.removeAll(); contentPlaceHolder.add(scrollPane); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/EclipseGUI.java0000644000175000017500000002127012533641120024446 0ustar benbenpackage com.baselet.plugin.gui; import java.awt.Cursor; import java.awt.Frame; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.util.Collection; import java.util.HashMap; import javax.swing.text.JTextComponent; import org.apache.log4j.Logger; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.widgets.Display; import com.baselet.control.CanCloseProgram; import com.baselet.control.config.Config; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; import com.baselet.gui.pane.OwnSyntaxPane; import com.baselet.plugin.gui.Contributor.ActionName; public class EclipseGUI extends BaseGUI { public enum Pane { PROPERTY, CUSTOMCODE, DIAGRAM } private static final Logger log = Logger.getLogger(EclipseGUI.class); private Editor editor; private final HashMap diagrams; private Contributor contributor; public EclipseGUI(CanCloseProgram main) { super(main); diagrams = new HashMap(); } @Override public void close(DiagramHandler diagram) { // eclipse does the closing } @Override public void closeWindow() { main.closeProgram(); } @Override public void diagramSelected(DiagramHandler handler) { // the menues are only visible if a diagram is selected. (contributor manages this) // AB: just update the export menu DrawPanel currentDiagram = CurrentGui.getInstance().getGui().getCurrentDiagram(); if (currentDiagram == null) { return; // Possible if method is called at loading a palette } boolean enable = handler != null && !currentDiagram.getGridElements().isEmpty(); contributor.setExportAsEnabled(enable); } @Override public void enablePasteMenuEntry() { if (contributor != null) { contributor.setPaste(true); } } @Override public CustomElementHandler getCurrentCustomHandler() { if (editor == null) { return null; } return editor.getCustomElementHandler(); } @Override public DrawPanel getCurrentDiagram() { if (editor == null) { return null; } return editor.getDiagram(); } @Override public int getMainSplitPosition() { return Config.getInstance().getMain_split_position(); // in Eclipse the Editors overwrite this constant everytime they are closed (editor.getMainSplitLocation() wouldn't work because the editor is already null) } @Override public int getRightSplitPosition() { return Config.getInstance().getRight_split_position(); } @Override public int getMailSplitPosition() { return Config.getInstance().getMail_split_position(); } @Override public String getSelectedPalette() { if (editor != null) { return editor.getSelectedPaletteName(); } return null; } @Override protected void init() {} @Override public void open(DiagramHandler diagram) { if (editor != null) { editor.open(diagram); } } @Override public void jumpTo(DiagramHandler diagram) { // not called by eclipse plugin (handles open by createEditor function) } @Override public void showPalette(String palette) { super.showPalette(palette); if (editor != null) { editor.showPalette(palette); } } @Override public void setCustomElementChanged(CustomElementHandler handler, boolean changed) { } @Override public void setCustomElementSelected(boolean selected) { if (editor != null && contributor != null) { contributor.setCustomElementSelected(selected); } } @Override public void setCustomPanelEnabled(boolean enable) { if (editor != null) { editor.setCustomPanelEnabled(enable); if (contributor != null) { contributor.setCustomPanelEnabled(enable); } } } @Override public void setMailPanelEnabled(boolean enable) { if (editor != null) { editor.setMailPanelEnabled(enable); } } @Override public boolean isMailPanelVisible() { return editor.isMailPanelVisible(); } @Override public void updateDiagramName(DiagramHandler diagram, String name) { Editor editor = diagrams.get(diagram); if (editor != null) { editor.diagramNameChanged(); } } @Override public void setDiagramChanged(DiagramHandler diagram, boolean changed) { Editor editor = diagrams.get(diagram); if (editor != null) { editor.dirtyChanged(); } } @Override public void setCursor(Cursor cursor) { if (editor != null) { editor.setCursor(cursor); } } public void registerEditorForDiagramHandler(Editor editor, DiagramHandler handler) { diagrams.put(handler, editor); } public void setCurrentDiagramHandler(DiagramHandler handler) { CurrentDiagram.getInstance().setCurrentDiagramHandler(handler); } public void setCurrentEditor(Editor editor) { this.editor = editor; } public void editorRemoved(Editor editor) { // Before removing the editor, we have to store the actual splitpositions and lastUsedPalette to variables so that a new editor has the same values Config.getInstance().setMain_split_position(editor.getMainSplitLocation()); Config.getInstance().setRight_split_position(editor.getRightSplitLocation()); Config.getInstance().setLastUsedPalette(getSelectedPalette()); diagrams.remove(editor.getDiagram().getHandler()); if (editor.equals(this.editor)) { this.editor = null; } } @Override public OwnSyntaxPane getPropertyPane() { if (editor != null) { return editor.getPropertyPane(); } else { return null; } } public void panelDoAction(Pane pane, ActionName actionName) { JTextComponent textpane = null; if (pane == Pane.PROPERTY) { textpane = editor.getPropertyPane().getTextComponent(); } else if (pane == Pane.CUSTOMCODE) { textpane = editor.getCustomPane(); } if (textpane != null) { if (actionName == ActionName.COPY) { textpane.copy(); } else if (actionName == ActionName.CUT) { textpane.cut(); int pos = textpane.getSelectionStart(); textpane.setCaretPosition(pos); } else if (actionName == ActionName.PASTE) { try { // We retrieve the content from the system clipboard Transferable cont = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); if (cont != null) { // If it's not null we save the length of the content and add the actual selection start int pos = ((String) cont.getTransferData(DataFlavor.stringFlavor)).length() + textpane.getSelectionStart(); textpane.paste(); // After pasting the clipboard content we want to set the actual cursor position to the end of the pasted content textpane.setCaretPosition(pos); } } catch (Exception e) { log.error(null, e); } } else if (actionName == ActionName.SELECTALL) { textpane.selectAll(); } } } @Override public void requestFocus() { if (editor != null) { editor.requestFocus(); } } public void setContributor(Contributor contributor) { this.contributor = contributor; } @Override public void elementsSelected(Collection selectedElements) { super.elementsSelected(selectedElements); if (contributor != null) { contributor.setElementsSelected(selectedElements); } } public void setPaneFocused(final Pane pane) { if (contributor != null) { // must be executed from within the SWT Display thread (see https://stackoverflow.com/questions/5980316/invalid-thread-access-error-with-java-swt) Display.getDefault().syncExec(new Runnable() { @Override public void run() { contributor.setGlobalActionHandlers(pane); } }); } } @Override public void setValueOfZoomDisplay(int i) { if (contributor != null) { contributor.updateZoomMenuRadioButton(i); } } @Override public void afterSaving() { super.afterSaving(); EclipseGUI.refreshWorkspace(); } @Override public void focusPropertyPane() { editor.focusPropertyPane(); } @Override public Frame getMainFrame() { return editor.getMainFrame(); } public static void refreshWorkspace() { IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); try { myWorkspaceRoot.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException e) { log.error("Error at refreshing the workspace", e); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/Contributor.java0000644000175000017500000002221412533641120025026 0ustar benbenpackage com.baselet.plugin.gui; import java.util.Collection; import java.util.List; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.part.EditorActionBarContributor; import com.baselet.control.constants.MenuConstants; import com.baselet.control.enums.Program; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.plugin.gui.EclipseGUI.Pane; public class Contributor extends EditorActionBarContributor { public enum ActionName { COPY, CUT, PASTE, SELECTALL } private final MenuFactoryEclipse menuFactory = MenuFactoryEclipse.getInstance(); private IAction customnew; private IAction customedit; private IAction undoActionGlobal; private IAction redoActionGlobal; private IAction printActionGlobal; private IAction copyActionDiagram; private IAction cutActionDiagram; private IAction pasteActionDiagram; private IAction deleteActionDiagram; private IAction selectallActionDiagram; private IAction searchActionDiagram; private IAction copyActionPropPanel; private IAction cutActionPropPanel; private IAction pasteActionPropPanel; private IAction selectAllActionPropPanel; private IAction copyActionCustomPanel; private IAction cutActionCustomPanel; private IAction pasteActionCustomPanel; private IAction selectAllActionCustomPanel; private List exportAsActionList; private boolean customPanelEnabled; private boolean custom_element_selected; private IMenuManager zoomMenu; public Contributor() { customPanelEnabled = false; custom_element_selected = false; } private Action createPanelAction(final Pane pane, final ActionName action) { Action copyActionPropPanel = new Action() { @Override public void run() { ((EclipseGUI) CurrentGui.getInstance().getGui()).panelDoAction(pane, action); } }; return copyActionPropPanel; } @Override public void init(IActionBars actionBars) { super.init(actionBars); customedit = menuFactory.createEditSelected(); customedit.setEnabled(false); undoActionGlobal = menuFactory.createUndo(); redoActionGlobal = menuFactory.createRedo(); printActionGlobal = menuFactory.createPrint(); cutActionDiagram = menuFactory.createCut(); cutActionDiagram.setEnabled(false); pasteActionDiagram = menuFactory.createPaste(); pasteActionDiagram.setEnabled(false); deleteActionDiagram = menuFactory.createDelete(); deleteActionDiagram.setEnabled(false); searchActionDiagram = menuFactory.createSearch(); copyActionDiagram = menuFactory.createCopy(); selectallActionDiagram = menuFactory.createSelectAll(); copyActionCustomPanel = createPanelAction(Pane.CUSTOMCODE, ActionName.COPY); cutActionCustomPanel = createPanelAction(Pane.CUSTOMCODE, ActionName.CUT); pasteActionCustomPanel = createPanelAction(Pane.CUSTOMCODE, ActionName.PASTE); selectAllActionCustomPanel = createPanelAction(Pane.CUSTOMCODE, ActionName.SELECTALL); copyActionPropPanel = createPanelAction(Pane.PROPERTY, ActionName.COPY); cutActionPropPanel = createPanelAction(Pane.PROPERTY, ActionName.CUT); pasteActionPropPanel = createPanelAction(Pane.PROPERTY, ActionName.PASTE); selectAllActionPropPanel = createPanelAction(Pane.PROPERTY, ActionName.SELECTALL); setGlobalActionHandlers(Pane.DIAGRAM); } @Override public void contributeToMenu(IMenuManager manager) { ((EclipseGUI) CurrentGui.getInstance().getGui()).setContributor(this); IMenuManager menu = new MenuManager(Program.getInstance().getProgramName().toString()); IMenuManager custom = new MenuManager(MenuConstants.CUSTOM_ELEMENTS); IMenuManager help = new MenuManager(MenuConstants.HELP); manager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, menu); custom.add(customnew = menuFactory.createNewCustomElement()); custom.add(menuFactory.createNewCustomElementFromTemplate(this)); custom.add(new Separator()); custom.add(menuFactory.createCustomElementsTutorial()); help.add(menuFactory.createOnlineHelp()); help.add(menuFactory.createOnlineSampleDiagrams()); help.add(menuFactory.createVideoTutorial()); help.add(new Separator()); help.add(menuFactory.createProgramHomepage()); help.add(menuFactory.createRateProgram()); help.add(new Separator()); help.add(menuFactory.createAboutProgram()); menu.add(menuFactory.createGenerate()); menu.add(menuFactory.createGenerateOptions()); zoomMenu = menuFactory.createZoom(); menu.add(zoomMenu); exportAsActionList = menuFactory.createExportAsActions(); IMenuManager export = new MenuManager("Export as"); for (IAction action : exportAsActionList) { export.add(action); } menu.add(export); menu.add(menuFactory.createEditCurrentPalette()); menu.add(custom); menu.add(menuFactory.createMailTo()); menu.add(new Separator()); menu.add(help); menu.add(menuFactory.createOptions()); } public void setExportAsEnabled(boolean enabled) { // AB: We cannot disable the MenuManager, so we have to disable every entry in the export menu :P for (IAction action : exportAsActionList) { action.setEnabled(enabled); } } public void setPaste(boolean value) { pasteActionDiagram.setEnabled(value); } public void setCustomElementSelected(boolean selected) { custom_element_selected = selected; customedit.setEnabled(selected && !customPanelEnabled); } public void setElementsSelected(Collection selectedElements) { if (selectedElements.isEmpty()) { deleteActionDiagram.setEnabled(false); cutActionDiagram.setEnabled(false); } else { cutActionDiagram.setEnabled(true); deleteActionDiagram.setEnabled(true); } } public boolean isCustomPanelEnabled() { return customPanelEnabled; } public void setCustomPanelEnabled(boolean enable) { customPanelEnabled = enable; customedit.setEnabled(!enable && custom_element_selected); customnew.setEnabled(!enable); searchActionDiagram.setEnabled(!enable); } public void setGlobalActionHandlers(Pane focusedPane) { // Global actions which are always the same getActionBars().setGlobalActionHandler(ActionFactory.UNDO.getId(), undoActionGlobal); getActionBars().setGlobalActionHandler(ActionFactory.REDO.getId(), redoActionGlobal); getActionBars().setGlobalActionHandler(ActionFactory.PRINT.getId(), printActionGlobal); // Specific actions depending on the active pane} if (focusedPane == Pane.DIAGRAM) { getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), copyActionDiagram); getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(), cutActionDiagram); getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteActionDiagram); getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteActionDiagram); getActionBars().setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectallActionDiagram); getActionBars().setGlobalActionHandler(ActionFactory.FIND.getId(), searchActionDiagram); } else if (focusedPane == Pane.CUSTOMCODE) { getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), copyActionCustomPanel); getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(), cutActionCustomPanel); getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteActionCustomPanel); getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), null); getActionBars().setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllActionCustomPanel); getActionBars().setGlobalActionHandler(ActionFactory.FIND.getId(), null); } else if (focusedPane == Pane.PROPERTY) { getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), copyActionPropPanel); getActionBars().setGlobalActionHandler(ActionFactory.CUT.getId(), cutActionPropPanel); getActionBars().setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteActionPropPanel); getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), null); getActionBars().setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllActionPropPanel); getActionBars().setGlobalActionHandler(ActionFactory.FIND.getId(), null); } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { getActionBars().updateActionBars(); } }); } public void updateZoomMenuRadioButton(int newGridSize) { for (IContributionItem item : zoomMenu.getItems()) { IAction action = ((ActionContributionItem) item).getAction(); int actionGridSize = Integer.parseInt(action.getText().substring(0, action.getText().length() - 2)); if (actionGridSize == newGridSize) { action.setChecked(true); } else { action.setChecked(false); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/plugin/gui/MenuFactoryEclipse.java0000644000175000017500000002031112533641120026251 0ustar benbenpackage com.baselet.plugin.gui; import static com.baselet.control.constants.MenuConstants.ABOUT_PROGRAM; import static com.baselet.control.constants.MenuConstants.COPY; import static com.baselet.control.constants.MenuConstants.CUSTOM_ELEMENTS_TUTORIAL; import static com.baselet.control.constants.MenuConstants.CUT; import static com.baselet.control.constants.MenuConstants.DELETE; import static com.baselet.control.constants.MenuConstants.EDIT_CURRENT_PALETTE; import static com.baselet.control.constants.MenuConstants.EDIT_SELECTED; import static com.baselet.control.constants.MenuConstants.EXPORT_AS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS_OPTIONS; import static com.baselet.control.constants.MenuConstants.MAIL_TO; import static com.baselet.control.constants.MenuConstants.NEW_CE; import static com.baselet.control.constants.MenuConstants.NEW_FROM_TEMPLATE; import static com.baselet.control.constants.MenuConstants.ONLINE_HELP; import static com.baselet.control.constants.MenuConstants.ONLINE_SAMPLE_DIAGRAMS; import static com.baselet.control.constants.MenuConstants.OPTIONS; import static com.baselet.control.constants.MenuConstants.PASTE; import static com.baselet.control.constants.MenuConstants.PRINT; import static com.baselet.control.constants.MenuConstants.PROGRAM_HOMEPAGE; import static com.baselet.control.constants.MenuConstants.RATE_PROGRAM; import static com.baselet.control.constants.MenuConstants.REDO; import static com.baselet.control.constants.MenuConstants.SEARCH; import static com.baselet.control.constants.MenuConstants.SELECT_ALL; import static com.baselet.control.constants.MenuConstants.UNDO; import static com.baselet.control.constants.MenuConstants.VIDEO_TUTORIAL; import static com.baselet.control.constants.MenuConstants.ZOOM; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; import org.apache.log4j.Logger; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import com.baselet.control.Main; import com.baselet.control.constants.Constants; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.gui.CurrentGui; import com.baselet.gui.menu.MenuFactory; public class MenuFactoryEclipse extends MenuFactory { private static final Logger log = Logger.getLogger(MenuFactoryEclipse.class); private static MenuFactoryEclipse instance = null; public static MenuFactoryEclipse getInstance() { if (instance == null) { instance = new MenuFactoryEclipse(); } return instance; } @Override public void doAction(final String menuItem, final Object param) { log.info("doAction " + menuItem); DiagramHandler actualHandler = CurrentDiagram.getInstance().getDiagramHandler(); // Edit Palette cannot be put in a separate invokeLater thread, or otherwise getActivePage() will be null! if (menuItem.equals(EDIT_CURRENT_PALETTE)) { String paletteName = Main.getInstance().getPalette().getFileHandler().getFullPathName(); IFileStore fileStore = EFS.getLocalFileSystem().getStore(new File(paletteName).toURI()); if (!fileStore.fetchInfo().isDirectory() && fileStore.fetchInfo().exists()) { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { IDE.openEditorOnFileStore(page, fileStore); } catch (PartInitException e) { log.error("Cannot open palette file", e); } } } else if (menuItem.equals(SEARCH)) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { CurrentGui.getInstance().getGui().enableSearch(true); } }); } else if (menuItem.equals(ZOOM) && actualHandler != null) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { CurrentDiagram.getInstance().getDiagramHandler().setGridAndZoom((Integer) param); } }); } // If the action is not overwritten, it is part of the default actions else { log.debug("super.doAction"); super.doAction(menuItem, param); log.debug("super.doAction complete"); } log.debug("doAction complete"); } public Action createOptions() { return createAction(OPTIONS, null); } public Action createOnlineHelp() { return createAction(ONLINE_HELP, null); } public Action createOnlineSampleDiagrams() { return createAction(ONLINE_SAMPLE_DIAGRAMS, null); } public Action createVideoTutorial() { return createAction(VIDEO_TUTORIAL, null); } public Action createProgramHomepage() { return createAction(PROGRAM_HOMEPAGE, null); } public Action createMailTo() { return createAction(MAIL_TO, null); } public Action createRateProgram() { return createAction(RATE_PROGRAM, null); } public Action createAboutProgram() { return createAction(ABOUT_PROGRAM, null); } public Action createNewCustomElement() { return createAction(NEW_CE, null); } public Action createCustomElementsTutorial() { return createAction(CUSTOM_ELEMENTS_TUTORIAL, null); } public Action createUndo() { return createAction(UNDO, null); } public Action createRedo() { return createAction(REDO, null); } public Action createPrint() { return createAction(PRINT, null); } public Action createCopy() { return createAction(COPY, null); } public Action createCut() { return createAction(CUT, null); } public Action createPaste() { return createAction(PASTE, null); } public Action createDelete() { return createAction(DELETE, null); } public Action createSelectAll() { return createAction(SELECT_ALL, null); } public Action createSearch() { return createAction(SEARCH, null); } public Action createEditSelected() { return createAction(EDIT_SELECTED, null); } public Action createEditCurrentPalette() { return createAction(EDIT_CURRENT_PALETTE, null); } public List createExportAsActions() { List actions = new ArrayList(); for (final String format : Constants.exportFormatList) { actions.add(createAction(format.toUpperCase() + "...", EXPORT_AS, format)); } return actions; } public IAction createGenerate() { return createAction(GENERATE_CLASS, null); } public IAction createGenerateOptions() { return createAction(GENERATE_CLASS_OPTIONS, null); } public IMenuManager createZoom() { final IMenuManager zoom = new MenuManager(ZOOM); for (String z : Constants.zoomValueList) { zoom.add(createAction(z, ZOOM, Integer.parseInt(z.substring(0, z.length() - 2)), IAction.AS_RADIO_BUTTON)); } return zoom; } private final List aList = new ArrayList(); public IMenuManager createNewCustomElementFromTemplate(final Contributor con) { IMenuManager menu = new MenuManager(NEW_FROM_TEMPLATE); for (String template : Main.getInstance().getTemplateNames()) { Action a = createAction(template, NEW_FROM_TEMPLATE, template); menu.add(a); aList.add(a); } menu.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { for (Action a : aList) { a.setEnabled(!con.isCustomPanelEnabled()); } } }); return menu; } private Action createAction(final String name, final String param) { return createAction(name, name, param); } private Action createAction(final String menuName, final String actionName, final Object param) { return createAction(menuName, actionName, param, IAction.AS_UNSPECIFIED); } private Action createAction(final String menuName, final String actionName, final Object param, int style) { return new Action(menuName, style) { @Override public void run() { doAction(actionName, param); } }; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/0000755000175000017500000000000012533641120021246 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/0000755000175000017500000000000012533641120022223 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/CanOpenDiagram.java0000644000175000017500000000016612533641120025701 0ustar benbenpackage com.baselet.control.util; public interface CanOpenDiagram { public void doOpen(final String filename); }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/RecentlyUsedFilesList.java0000644000175000017500000000203512533641120027313 0ustar benbenpackage com.baselet.control.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class RecentlyUsedFilesList implements Iterable { private static RecentlyUsedFilesList instance = new RecentlyUsedFilesList(); public static RecentlyUsedFilesList getInstance() { return instance; } private static final int LIST_LENGTH = 10; private final List recentFiles = new ArrayList(); public void add(String filename) { if (recentFiles.contains(filename)) { recentFiles.remove(filename); } recentFiles.add(0, filename); if (recentFiles.size() > RecentlyUsedFilesList.LIST_LENGTH) { recentFiles.remove(RecentlyUsedFilesList.LIST_LENGTH); } } public List getList() { return recentFiles; } @Override public Iterator iterator() { return recentFiles.iterator(); } public void addAll(List items) { recentFiles.addAll(items); } public boolean isEmpty() { return recentFiles.isEmpty(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/RunningFileChecker.java0000644000175000017500000000173212533641120026576 0ustar benbenpackage com.baselet.control.util; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.TimerTask; public class RunningFileChecker extends TimerTask { private final File file; private final File ok_file; private final CanOpenDiagram canOpenDiagram; public RunningFileChecker(String filename, String okfile, CanOpenDiagram canOpenDiagram) { this.canOpenDiagram = canOpenDiagram; file = new File(filename); ok_file = new File(okfile); } @Override public void run() { try { Utils.safeCreateFile(file, false); BufferedReader reader = new BufferedReader(new FileReader(file)); String filename = reader.readLine(); reader.close(); if (filename != null) { Utils.safeCreateFile(ok_file, true); Utils.safeDeleteFile(file, false); Utils.safeCreateFile(file, true); canOpenDiagram.doOpen(filename); } } catch (Exception ex) { ex.printStackTrace(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/Path.java0000644000175000017500000000635212533641120023770 0ustar benbenpackage com.baselet.control.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.jar.JarFile; import java.util.jar.Manifest; import com.baselet.control.enums.Program; public class Path { private static String tempDir; private static String homeProgramDir; public static String config() { return userHome() + File.separator + Program.getInstance().getConfigName(); } private static String userHome() { String homeDir = userHomeBase(); if (!homeDir.endsWith(File.separator)) { homeDir += File.separator; } File homeDirFile = new File(homeDir + Program.getInstance().getProgramName()); if (!homeDirFile.exists()) { Utils.safeMkDir(homeDirFile, true); } return homeDirFile.getAbsolutePath(); } private static String userHomeBase() { try { String xdgConfigHome = System.getenv("XDG_CONFIG_HOME"); // use env variable $XDG_CONFIG_HOME if it's set if (xdgConfigHome != null) { return xdgConfigHome; } } catch (Exception e) { /* if env variable cannot be read, ignore it */} return System.getProperty("user.home"); } public static String customElements() { return homeProgram() + "custom_elements/"; } public static String temp() { if (tempDir == null) { String tmp = System.getProperty("java.io.tmpdir"); if (!tmp.endsWith(File.separator)) { tmp = tmp + File.separator; } tempDir = tmp; } return tempDir; } /** * STANDALONE NOJAR: * STANDALONE JAR: * ECLIPSE NOJAR: * ECLIPSE JAR: // */ public static String homeProgram() { return homeProgramDir; } public static void setHomeProgram(String homeProgramDir) { Path.homeProgramDir = homeProgramDir; } /** * STANDALONE NOJAR: /bin/ * STANDALONE JAR: /.jar * ECLIPSE NOJAR: * ECLIPSE JAR: /.jar */ public static String executable() { String path = null; URL codeSourceUrl = Path.class.getProtectionDomain().getCodeSource().getLocation(); try { // Convert URL to URI to avoid HTML problems with special characters like space,ä,ö,ü,... path = codeSourceUrl.toURI().getPath(); } catch (URISyntaxException e) {/* path stays null */} if (path == null) { // URI2URL Conversion failed, because URI.getPath() returned null OR because of an URISyntaxException // In this case use the URL and replace special characters manually (for now only space) path = codeSourceUrl.getPath().replace("%20", " "); } return path; } public static Manifest manifest() throws IOException { Manifest manifest; if (Path.executable().endsWith(".jar")) { JarFile jarFile = null; try { jarFile = new JarFile(Path.executable()); manifest = jarFile.getManifest(); } finally { if (jarFile != null) { jarFile.close(); } } } else { FileInputStream is = new FileInputStream(Path.homeProgram() + "META-INF" + File.separator + "MANIFEST.MF"); manifest = new Manifest(is); is.close(); } return manifest; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/util/Utils.java0000644000175000017500000001645612533641120024202 0ustar benbenpackage com.baselet.control.util; import java.awt.BasicStroke; import java.awt.RenderingHints; import java.awt.Stroke; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Vector; import com.baselet.control.basics.geom.Point; import com.baselet.control.constants.Constants; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.LineType; import com.baselet.diagram.draw.DoubleStroke; public abstract class Utils { private Utils() {} // private constructor to avoid instantiation // Not used public static File createRandomFile(String extension) { File randomFile = new File(Path.homeProgram() + "tmp.diagram." + new Date().getTime() + "." + extension); randomFile.deleteOnExit(); return randomFile; } public static Point normalize(Point p, int pixels) { Point ret = new Point(); double d = Math.sqrt(p.x * p.x + p.y * p.y); ret.x = (int) (p.x / d * pixels); ret.y = (int) (p.y / d * pixels); return ret; } public static Vector decomposeStringsIncludingEmptyStrings(String s, String delimiter) { return decomposeStringsWFilter(s, delimiter, false, false); } public static Vector decomposeStringsWithEmptyLines(String s) { return Utils.decomposeStringsWFilter(s, Constants.NEWLINE, true, false); } public static Vector decomposeStringsWithComments(String s) { return Utils.decomposeStringsWFilter(s, Constants.NEWLINE, false, true); } public static Vector decomposeStrings(String s, String delimiter) { return Utils.decomposeStringsWFilter(s, delimiter, true, true); } public static Vector decomposeStrings(String s) { return decomposeStrings(s, Constants.NEWLINE); } // TODO: Decomposing should be moved to Properties.class. At the moment OldGridElement uses this method and NewGridElement the one in Properties.class private static Vector decomposeStringsWFilter(String fullString, String delimiter, boolean filterComments, boolean filterNewLines) { Vector returnVector = new Vector(); String compatibleFullString = fullString.replaceAll("\r\n", delimiter); // compatibility to windows \r\n for (String line : compatibleFullString.split("\\" + delimiter)) { if (filterComments && line.matches("((//)|(fg=)|(bg=)|(autoresize=)|(layer=)|(group=)).*")) { continue; } else if (filterNewLines && line.isEmpty()) { continue; } else { returnVector.add(line); } } return returnVector; } public static String composeStrings(Vector v, String delimiter) { String ret = null; if (v != null) { for (int i = 0; i < v.size(); i++) { if (ret == null) { ret = v.elementAt(i); } else { ret = ret + delimiter + v.elementAt(i); } } } if (ret == null) { ret = ""; } return ret; } public static Stroke getStroke(LineType lineType, float lineThickness) { // If the lineThickness is not supported, the default type is used if (lineThickness < 0) { lineThickness = (float) FacetConstants.LINE_WIDTH_DEFAULT; } Stroke stroke = null; if (lineType == LineType.SOLID) { stroke = new BasicStroke(lineThickness); } else if (lineType == LineType.DASHED) { stroke = new BasicStroke(lineThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, new float[] { 8.0f, 5.0f }, 0.0f); } else if (lineType == LineType.DOTTED) { stroke = new BasicStroke(lineThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, new float[] { 1.0f, 2.0f }, 0.0f); } else if (lineType == LineType.DOUBLE) { stroke = new DoubleStroke(lineThickness, 4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, null, 0.0f); } else if (lineType == LineType.DOUBLE_DASHED) { stroke = new DoubleStroke(lineThickness, 4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, new float[] { 8.0f, 5.0f }, 0.0f); } else if (lineType == LineType.DOUBLE_DOTTED) { stroke = new DoubleStroke(lineThickness, 3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, new float[] { 1.0f, 2.0f }, 0.0f); } return stroke; } public static Map getUxRenderingQualityHigh(boolean subpixelRendering) { HashMap renderingHints = new HashMap(); renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); renderingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); renderingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); if (subpixelRendering) { renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); } else { renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); } renderingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); return renderingHints; } /** * Calculates and returns the angle of the line defined by the coordinates */ public static double getAngle(double x1, double y1, double x2, double y2) { double res; double x = x2 - x1; double y = y2 - y1; res = Math.atan(y / x); if (x >= 0.0 && y >= 0.0) { res += 0.0; } else if (x < 0.0 && y >= 0.0) { res += Math.PI; } else if (x < 0.0 && y < 0.0) { res += Math.PI; } else if (x >= 0.0 && y < 0.0) { res += 2.0 * Math.PI; } return res; } /** * eg: createDoubleArrayFromTo(5, 6, 0.1) = [5, 5.1, 5.2, ..., 5.9, 6]
* eg: createDoubleArrayFromTo(10, 20, 3) = [10, 13, 16, 19, 22]
* * @param min first value of the result array * @param max if this value is reached (or passed if it's not dividable through "step") the array is finished * @param step the stepsize of the array */ public static Double[] createDoubleArrayFromTo(Double min, Double max, Double step) { if (min > max) { return null; } int range = (int) Math.ceil((max - min) / step + 1); Double[] returnArray = new Double[range]; for (int i = 0; i < range; i++) { returnArray[i] = min + i * step; } return returnArray; } public static Double[] createDoubleArrayFromTo(Double min, Double max) { return createDoubleArrayFromTo(min, max, 1D); } public static void safeCreateFile(File file, boolean errorIfFileExists) { try { boolean success = file.createNewFile(); if (!success && errorIfFileExists) { throw new RuntimeException("Cannot create file " + file.getAbsolutePath() + " because it already exists"); } } catch (IOException e) { throw new RuntimeException("Cannot create file " + file.getAbsolutePath()); } } public static void safeDeleteFile(File file, boolean errorIfFailed) { boolean success = file.delete(); if (!success && errorIfFailed) { throw new RuntimeException("Cannot delete file " + file.getAbsolutePath()); } } public static void safeMkDir(File file, boolean errorIfFailed) { boolean success = file.mkdir(); if (!success && errorIfFailed) { throw new RuntimeException("Cannot make dir " + file.getAbsolutePath()); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/constants/0000755000175000017500000000000012533641120023262 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/constants/SystemInfo.java0000644000175000017500000000147112533641120026230 0ustar benbenpackage com.baselet.control.constants; import com.baselet.control.enums.Metakey; import com.baselet.control.enums.Os; public class SystemInfo { public static final Os OS; public static final String JAVA_VERSION = java.lang.System.getProperty("java.specification.version"); public static final Metakey META_KEY; static { String os = java.lang.System.getProperty("os.name").toUpperCase(); if (os.startsWith("WINDOWS")) { OS = Os.WINDOWS; } else if (os.startsWith("MAC")) { OS = Os.MAC; } else if (os.startsWith("LINUX")) { OS = Os.LINUX; } else if (os.contains("UNIX") || os.contains("BSD")) { OS = Os.UNIX; } else { OS = Os.UNKNOWN; } if (SystemInfo.OS == Os.MAC) { META_KEY = Metakey.CMD; } else { META_KEY = Metakey.CTRL; } } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/constants/Constants.java0000644000175000017500000001406312533641120026105 0ustar benbenpackage com.baselet.control.constants; import java.awt.Color; import java.awt.Cursor; import java.awt.Font; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import com.baselet.control.enums.Program; public abstract class Constants extends SharedConstants { private Constants() {} // private constructor to avoid instantiation /**** NEWLINE CHARACTER AND DEFAULT HELP- AND MAILTEXT ****/ public static final String NEWLINE = "\n"; public static final String COMMENT = "//"; //@formatter:off public static String getDefaultHelptext() { String returnString = "// Uncomment the following line to change the fontsize and font:" + NEWLINE + "// fontsize=14" + NEWLINE + "// fontfamily=SansSerif //possible: SansSerif,Serif,Monospaced" + NEWLINE + "" + NEWLINE + "" + NEWLINE + "//////////////////////////////////////////////////////////////////////////////////////////////" + NEWLINE + "// Welcome to " + Program.getInstance().getProgramName() + "!" + NEWLINE + "//" + NEWLINE + "// Double-click on elements to add them to the diagram, or to copy them" + NEWLINE + "// Edit elements by modifying the text in this panel" + NEWLINE + "// Hold " + SystemInfo.META_KEY + " to select multiple elements" + NEWLINE + "// Use " + SystemInfo.META_KEY + "+mouse to select via lasso" + NEWLINE + "//" + NEWLINE + "// Use +/- or " + SystemInfo.META_KEY + "+mouse wheel to zoom" + NEWLINE + "// Drag a whole relation at its central square icon" + NEWLINE + "//" + NEWLINE + "// Press " + SystemInfo.META_KEY + "+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word)" + NEWLINE + "// Edit the files in the \"palettes\" directory to create your own element palettes" + NEWLINE + "//" + NEWLINE + "// Select \"Custom Elements > New...\" to create new element types" + NEWLINE; returnString += "//////////////////////////////////////////////////////////////////////////////////////////////" + NEWLINE + "" + NEWLINE + "" + NEWLINE + "// This text will be stored with each diagram; use it for notes."; return returnString; } public static String getDefaultMailtext() { return "Type your message here.." + NEWLINE + "" + NEWLINE + "__" + NEWLINE + "To edit the diagram, open the attached " + Program.getInstance().getExtension() + "-file with the free editing tool " + Program.getInstance().getProgramName() + " (" + Program.getInstance().getWebsite() + ")"; } //@formatter:on /**** EXPORT FORMATS ****/ public static final List exportFormatList = Arrays.asList(new String[] { "bmp", "eps", "gif", "jpg", "pdf", "png", "svg" }); /**** ZOOM VALUES ****/ public static final ArrayList zoomValueList = new ArrayList(); static { for (int i = 1; i <= 20; i++) { zoomValueList.add(i + "0%"); } } /**** REGULAR EXPRESSIONS ****/ public static final String REGEX_FLOAT = "(\\d+(\\.\\d+)?)"; /**** OTHER CONSTANTS ****/ public static final double EXPORT_DISPLACEMENT = 0.5; public static final String MANIFEST_BUNDLE_NAME = "Bundle-Name"; public static final String MANIFEST_BUNDLE_VERSION = "Bundle-Version"; public static final String LOG4J_PROPERTIES = "log4j.properties"; public static final int NOTIFICATION_SHOW_TIME = 3000; public static final String CUSTOM_ELEMENT_CLASSNAME = "CustomElementImpl"; public static final int DEFAULTGRIDSIZE = 10; public static final int INTERFACE_LINE_LENGTH = 40; public static final int CUSTOM_ELEMENT_COMPILE_INTERVAL = 500; public static final Cursor LR_CURSOR = new Cursor(Cursor.E_RESIZE_CURSOR); public static final Cursor TB_CURSOR = new Cursor(Cursor.N_RESIZE_CURSOR); public static final Cursor NW_CURSOR = new Cursor(Cursor.NW_RESIZE_CURSOR); public static final Cursor NE_CURSOR = new Cursor(Cursor.NE_RESIZE_CURSOR); public static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR); public static final Cursor MOVE_CURSOR = new Cursor(Cursor.MOVE_CURSOR); public static final Cursor DEFAULT_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR); public static final Cursor CROSS_CURSOR = new Cursor(Cursor.CROSSHAIR_CURSOR); public static final Cursor TEXT_CURSOR = new Cursor(Cursor.TEXT_CURSOR); public static final String DELIMITER_ENTITIES = "~~~~~|||||~~~~~|||||"; public static final String DELIMITER_STATE_AND_HIDDEN_STATE = "/////<<<< fontFamilyList = Arrays.asList(new String[] { Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED }); public static final List lookAndFeels = Arrays.asList(UIManager.getInstalledLookAndFeels()); protected static final String DEFAULT_STRING = "Default"; public static final Comparator DEFAULT_FIRST_COMPARATOR = new Comparator() { @Override public int compare(String s1, String s2) { // "UML Common Elements" before "Default" before anything else for (String prefixFirst : Arrays.asList("UML Common Elements", Constants.DEFAULT_STRING)) { if (s1.startsWith(prefixFirst) && !s2.startsWith(prefixFirst)) { return -1; } if (s2.startsWith(prefixFirst) && !s1.startsWith(prefixFirst)) { return 1; } } // "Deprecated" after "Plot" after anything else for (String prefixLast : Arrays.asList("Deprecated", "Plots")) { if (s1.startsWith(prefixLast) && !s2.startsWith(prefixLast)) { return 1; } if (s2.startsWith(prefixLast) && !s1.startsWith(prefixLast)) { return -1; } } return s1.compareTo(s2); } }; public static final int MIN_MAIN_SPLITPANEL_SIZE = 100; public static final int MIN_MAIL_SPLITPANEL_SIZE = 250; } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/CanCloseProgram.java0000644000175000017500000000022612533641120025130 0ustar benbenpackage com.baselet.control; public interface CanCloseProgram { // called by UI when main is closed public abstract void closeProgram(); }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/Main.java0000644000175000017500000004072112533641120023001 0ustar benbenpackage com.baselet.control; import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileWriter; import java.io.PrintWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Properties; import java.util.Timer; import java.util.TreeMap; import java.util.jar.Attributes; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import javax.swing.filechooser.FileSystemView; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import com.baselet.control.config.Config; import com.baselet.control.config.handler.ConfigHandler; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; import com.baselet.control.util.CanOpenDiagram; import com.baselet.control.util.Path; import com.baselet.control.util.RecentlyUsedFilesList; import com.baselet.control.util.RunningFileChecker; import com.baselet.control.util.Utils; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.diagram.Notifier; import com.baselet.diagram.PaletteHandler; import com.baselet.diagram.UpdateCheckTimerTask; import com.baselet.diagram.io.OpenFileChooser; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; import com.baselet.gui.pane.OwnSyntaxPane; import com.baselet.gui.standalone.StandaloneGUI; public class Main implements CanCloseProgram, CanOpenDiagram { private static final Logger log = Logger.getLogger(Main.class); private static Main main = new Main(); private static String tmp_file; private static String tmp_read_file; private static boolean file_created = false; private GridElement editedGridElement; private TreeMap palettes; private final ArrayList diagrams = new ArrayList(); public static Main getInstance() { return main; } public static void main(final String[] args) { initHomeProgramPath(); main.initLogger(); main.readManifestInfo(); ConfigHandler.loadConfig(); tmp_file = Program.getInstance().getProgramName().toLowerCase() + ".tmp"; tmp_read_file = Program.getInstance().getProgramName().toLowerCase() + "_1.tmp"; if (args.length != 0) { String action = null; String format = null; String filename = null; String output = null; for (String arg : args) { if (arg.startsWith("-action=")) { action = arg.substring(8); } else if (arg.startsWith("-format=")) { format = arg.substring(8); } else if (arg.startsWith("-filename=")) { filename = arg.substring(10); } else if (arg.startsWith("-output=")) { output = arg.substring(8); } } // Program started by double-click on diagram file (either diagram filename is passed without prefix or with -filename=... prefix) if (action == null && format == null && (filename != null || args.length == 1)) { if (filename == null) { filename = args[0]; } if (!alreadyRunningChecker(false) || !sendFileNameToRunningApplication(filename)) { main.init(new StandaloneGUI(main)); main.doOpen(filename); } } else if (action != null && format != null && filename != null) { if (action.equals("convert")) { Program.getInstance().setRuntimeType(RuntimeType.BATCH); String[] splitFilename = filename.split("(/|\\\\)"); String localName = splitFilename[splitFilename.length - 1]; String dir = filename.substring(0, filename.length() - localName.length()); if (dir.isEmpty()) { dir = "."; } FileFilter fileFilter = new WildcardFileFilter(localName); File[] files = new File(dir).listFiles(fileFilter); if (files != null) { for (File file : files) { doConvert(file, format, output); } } } else { printUsage(); } } else { printUsage(); } } else { // no arguments specified alreadyRunningChecker(true); // start checker if (Config.getInstance().isCheckForUpdates()) { new Timer("Update Checker", true).schedule(UpdateCheckTimerTask.getInstance(), 0); } main.init(new StandaloneGUI(main)); main.doNew(); } } private static void initHomeProgramPath() { String tempPath, realPath; tempPath = Path.executable(); tempPath = tempPath.substring(0, tempPath.length() - 1); tempPath = tempPath.substring(0, tempPath.lastIndexOf('/') + 1); realPath = new File(tempPath).getAbsolutePath() + "/"; Path.setHomeProgram(realPath); } public void init(BaseGUI gui) { CurrentGui.getInstance().setGui(gui); ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE); // Tooltips should not hide after some time gui.initGUI(); // show gui } public void initLogger() { String log4jFilePath = Path.homeProgram() + Constants.LOG4J_PROPERTIES; try { // If no log4j.properties file exists, we create a simple one if (!new File(log4jFilePath).exists()) { File tempLog4jFile = File.createTempFile(Constants.LOG4J_PROPERTIES, null); tempLog4jFile.deleteOnExit(); log4jFilePath = tempLog4jFile.getAbsolutePath(); Writer writer = new BufferedWriter(new FileWriter(tempLog4jFile)); writer.write( "log4j.rootLogger=ERROR, SYSTEM_OUT\n" + "log4j.appender.SYSTEM_OUT=org.apache.log4j.ConsoleAppender\n" + "log4j.appender.SYSTEM_OUT.layout=org.apache.log4j.PatternLayout\n" + "log4j.appender.SYSTEM_OUT.layout.ConversionPattern=%6r | %-5p | %-30c - \"%m\"%n\n"); writer.close(); } Properties props = new Properties(); props.put("PROJECT_PATH", Path.homeProgram()); // Put homepath as relative variable in properties file FileInputStream inStream = new FileInputStream(log4jFilePath); props.load(inStream); inStream.close(); PropertyConfigurator.configure(props); log.info("Logger configuration initialized"); } catch (Exception e) { System.err.println("Initialization of " + Constants.LOG4J_PROPERTIES + " failed:"); e.printStackTrace(); } } private void readManifestInfo() { try { Attributes attributes = Path.manifest().getMainAttributes(); Program.getInstance().init(attributes.getValue(Constants.MANIFEST_BUNDLE_VERSION)); } catch (Exception e) { log.error("Cannot read manifest", e); throw new RuntimeException(e); } } public void displayError(String error) { JOptionPane.showMessageDialog(CurrentGui.getInstance().getGui().getMainFrame(), error, "ERROR", JOptionPane.ERROR_MESSAGE); } private static void printToConsole(String text) { System.out.println(text); } private static void printUsage() { StringBuilder formatBuilder = new StringBuilder("pdf|svg|eps"); for (String format : ImageIO.getWriterFileSuffixes()) { formatBuilder.append("|").append(format); } printToConsole("USAGE: -action=convert -format=(" + formatBuilder.toString() + ") -filename=inputfile." + Program.getInstance().getExtension() + " [-output=outputfile[.extension]]"); } public static void doConvert(File inputFile, String outputFormat, String outputParam) { if (!inputFile.exists()) { printToConsole("File '" + inputFile.getAbsolutePath() + "' not found."); return; } DiagramHandler handler = new DiagramHandler(inputFile); String outputFileName = determineOutputName(inputFile, outputFormat, outputParam); try { handler.getFileHandler().doExportAs(outputFormat, new File(outputFileName)); printToConsole("Conversion finished: \"" + inputFile.getAbsolutePath() + "\" to \"" + outputParam + "\""); } catch (Exception e) { printToConsole(e.getMessage()); } } private static String determineOutputName(File inputFile, String outputFormat, String outputParam) { String outputFileName; if (outputParam == null) { outputFileName = inputFile.getAbsolutePath(); } else if (new File(outputParam).isDirectory()) { // if outputdir already exists outputFileName = outputParam + File.separator + inputFile.getName(); } else { outputFileName = outputParam; } return createBatchOutputName(outputFormat, outputFileName); } private static String createBatchOutputName(String extension, String fileName) { if (fileName.endsWith(extension)) { return fileName; } else { return fileName + "." + extension; } } private static boolean alreadyRunningChecker(boolean force) { try { File f = new File(Path.temp() + tmp_file); if (f.exists() && !force) { return true; } Utils.safeCreateFile(f, false); file_created = true; new Timer("alreadyRunningChecker", true).schedule(new RunningFileChecker(Path.temp() + tmp_file, Path.temp() + tmp_read_file, main), 0, 1000); } catch (Exception ex) { ex.printStackTrace(); return true; } return false; } private static boolean sendFileNameToRunningApplication(String filename) { // send the filename per file to the running application File f1 = new File(Path.temp() + tmp_file); boolean write_successful = true; try { PrintWriter writer = new PrintWriter(f1); writer.println(filename); writer.close(); } catch (Exception ex) { write_successful = false; } try { Thread.sleep(2000); } catch (InterruptedException ex) {/* no special handling */} File f2 = new File(Path.temp() + tmp_read_file); if (!f2.exists() || !write_successful) {// if the ok file does not exist or the filename couldnt be written. alreadyRunningChecker(true); return false; } else { Utils.safeDeleteFile(f2, false); } return true; } public void setPropertyPanelToCustomElement(GridElement e) { editedGridElement = e; } public void setPropertyPanelToGridElement(final GridElement e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { setPropertyPanelToGridElementHelper(e); } }); } private void setPropertyPanelToGridElementHelper(GridElement e) { editedGridElement = e; OwnSyntaxPane propertyPane = CurrentGui.getInstance().getGui().getPropertyPane(); if (e != null) { propertyPane.switchToElement(e); } else { DiagramHandler handler = CurrentDiagram.getInstance().getDiagramHandler(); if (handler == null) { propertyPane.switchToNonElement(""); } else { propertyPane.switchToNonElement(handler.getHelpText()); } } } public void doNew() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { doNewHelper(); } }); } private void doNewHelper() { if (lastTabIsEmpty()) { return; // If the last tab is empty do nothing (it's already new) } DiagramHandler diagram = new DiagramHandler(null); diagrams.add(diagram); CurrentGui.getInstance().getGui().open(diagram); if (diagrams.size() == 1) { setPropertyPanelToGridElement(null); } } public void doOpenFromFileChooser() { List files = new OpenFileChooser().getFilesToOpen(CurrentGui.getInstance().getGui().getMainFrame()); for (String file : files) { doOpen(file); } } @Override public void doOpen(final String filename) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { doOpenHelper(filename); } }); } private void doOpenHelper(String filename) { File file = new File(filename); if (!file.exists()) { Notifier.getInstance().showNotification(filename + " does not exist"); return; } Config.getInstance().setOpenFileHome(file.getParent()); DiagramHandler handler = getDiagramHandlerForFile(filename); if (handler != null) { // File is already opened -> jump to the tab CurrentGui.getInstance().getGui().jumpTo(handler); Notifier.getInstance().showNotification("switched to " + filename); } else { if (lastTabIsEmpty()) { diagrams.get(diagrams.size() - 1).doClose(); // If the last tab is empty close it (the opened diagram replaces the new one) } editedGridElement = null; // must be set to null here, otherwise the change listener of the property panel will change element text to help_text of diagram (see google code Issue 174) DiagramHandler diagram = new DiagramHandler(file); diagrams.add(diagram); CurrentGui.getInstance().getGui().open(diagram); if (diagrams.size() == 1) { setPropertyPanelToGridElement(null); } RecentlyUsedFilesList.getInstance().add(filename); Notifier.getInstance().showNotification(filename + " opened"); } } private DiagramHandler getDiagramHandlerForFile(String file) { for (DiagramHandler d : diagrams) { if (d.getFullPathName().equalsIgnoreCase(file)) { return d; } } return null; } /** * If the last diagram tab and it's undo history (=controller) is empty return true, else return false */ private boolean lastTabIsEmpty() { if (!diagrams.isEmpty()) { DiagramHandler lastDiagram = diagrams.get(diagrams.size() - 1); if (lastDiagram.getController().isEmpty() && lastDiagram.getDrawPanel().getGridElements().isEmpty()) { return true; } } return false; } /** * called by UI when main is closed */ @Override public void closeProgram() { ConfigHandler.saveConfig(CurrentGui.getInstance().getGui()); if (file_created) { Utils.safeDeleteFile(new File(Path.temp() + tmp_file), true); } } public TreeMap getPalettes() { if (palettes == null) { palettes = new TreeMap(Constants.DEFAULT_FIRST_COMPARATOR); // scan palettes List palettes = scanForPalettes(); for (File palette : palettes) { this.palettes.put(getFilenameWithoutExtension(palette), new PaletteHandler(palette)); } } return palettes; } private String getFilenameWithoutExtension(File file) { return file.getName().substring(0, file.getName().indexOf(".")); } private List scanForPalettes() { // scan palettes directory... FileSystemView fileSystemView = FileSystemView.getFileSystemView(); File[] paletteFiles = fileSystemView.getFiles(new File(Path.homeProgram() + "palettes/"), false); List palettes = new ArrayList(); for (File palette : paletteFiles) { if (palette.getName().endsWith("." + Program.getInstance().getExtension())) { palettes.add(palette); } } return palettes; } public List getTemplateNames() { ArrayList templates = new ArrayList(); // scan palettes directory... FileSystemView fileSystemView = FileSystemView.getFileSystemView(); File[] templateFiles = fileSystemView.getFiles(new File(Path.customElements()), false); for (File template : templateFiles) { if (template.getName().endsWith(".java")) { templates.add(template.getName().substring(0, template.getName().length() - 5)); } } Collections.sort(templates, Constants.DEFAULT_FIRST_COMPARATOR); return templates; } public List getDiagrams() { return diagrams; } public Collection getDiagramsAndPalettes() { List returnList = new ArrayList(getDiagrams()); returnList.addAll(getPalettes().values()); return returnList; } public GridElement getEditedGridElement() { return editedGridElement; } public PaletteHandler getPalette() { String name = CurrentGui.getInstance().getGui().getSelectedPalette(); if (name != null) { return getPalettes().get(name); } return null; } public DrawPanel getPalettePanel() { return getPalette().getDrawPanel(); } /** * Workaround to avoid storing the handler directly in the GridElement * (necessary as a first step in the direction of GridElements which do not know where they are painted) */ private static HashMap gridElementToHandlerMapping = new HashMap(); public static DiagramHandler getHandlerForElement(GridElement element) { return gridElementToHandlerMapping.get(element); } public static DiagramHandler setHandlerForElement(GridElement element, DiagramHandler handler) { return gridElementToHandlerMapping.put(element, handler); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/basics/0000755000175000017500000000000012533641120022512 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/basics/Converter.java0000644000175000017500000000304712533641120025330 0ustar benbenpackage com.baselet.control.basics; import java.awt.Color; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.draw.helper.ColorOwn; public class Converter { public static java.awt.Rectangle convert(Rectangle in) { if (in == null) { return null; } return new java.awt.Rectangle(in.x, in.y, in.width, in.height); } public static Rectangle convert(java.awt.Rectangle in) { if (in == null) { return null; } return new Rectangle(in.x, in.y, in.width, in.height); } public static java.awt.Dimension convert(Dimension in) { if (in == null) { return null; } return new java.awt.Dimension(in.width, in.height); } public static Dimension convert(java.awt.Dimension in) { if (in == null) { return null; } return new Dimension(in.width, in.height); } public static java.awt.Point convert(Point in) { if (in == null) { return null; } return new java.awt.Point(in.x, in.y); } public static Point convert(java.awt.Point in) { if (in == null) { return null; } return new Point(in.x, in.y); } public static ColorOwn convert(Color in) { if (in == null) { return null; } return new ColorOwn(in.getRed(), in.getGreen(), in.getBlue(), in.getAlpha()); } public static Color convert(ColorOwn in) { if (in == null) { return null; } return new Color(in.getRed(), in.getGreen(), in.getBlue(), in.getAlpha()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/0000755000175000017500000000000012533641120022513 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/Config.java0000644000175000017500000001472212533641120024571 0ustar benbenpackage com.baselet.control.config; import java.awt.Font; import java.awt.Point; import java.io.File; import javax.swing.UIManager; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Os; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; public class Config { private static Config instance = new Config(); public static Config getInstance() { return instance; } private final String DEFAULT_FILE_HOME = System.getProperty("user.dir"); private String uiManager; private String openFileHome = DEFAULT_FILE_HOME; private String saveFileHome = DEFAULT_FILE_HOME; private String programVersion; private String lastUsedPalette = ""; // default is empty string not null because null cannot be stored as property private String pdfExportFont = ""; // eg in Windows: "pdf_export_font = c:/windows/fonts/msgothic.ttc,1" private String pdfExportFontBold = ""; private String pdfExportFontItalic = ""; private String pdfExportFontBoldItalic = ""; private boolean checkForUpdates = true; private int printPadding = 20; private Point program_location = new Point(5, 5); private Dimension program_size = new Dimension(960, 750); private int mail_split_position = 250; private int right_split_position = 400; private int main_split_position = 600; private boolean enable_custom_elements = true; private boolean show_grid = false; private boolean start_maximized = false; private String defaultFontFamily = Font.SANS_SERIF; private Integer defaultFontsize = 14; private Integer propertiesPanelFontsize = 11; public Config() { initUiManager(); } private void initUiManager() { // The default MacOS theme looks ugly, therefore we set metal if (SystemInfo.OS == Os.MAC) { uiManager = "javax.swing.plaf.metal.MetalLookAndFeel"; } else if (Program.getInstance().getRuntimeType() == RuntimeType.ECLIPSE_PLUGIN && UIManager.getSystemLookAndFeelClassName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) { uiManager = "javax.swing.plaf.metal.MetalLookAndFeel"; } else { uiManager = UIManager.getSystemLookAndFeelClassName(); } } public String getUiManager() { return uiManager; } public void setUiManager(String uiManager) { this.uiManager = uiManager; } public String getOpenFileHome() { if (new File(openFileHome).exists()) { return openFileHome; } else { // if stored location doesn't exist, return default value return DEFAULT_FILE_HOME; } } public void setOpenFileHome(String openFileHome) { this.openFileHome = openFileHome; } public String getSaveFileHome() { if (new File(saveFileHome).exists()) { return saveFileHome; } else { // if stored location doesn't exist, return default value return DEFAULT_FILE_HOME; } } public void setSaveFileHome(String saveFileHome) { this.saveFileHome = saveFileHome; } public void setProgramVersion(String cfgVersion) { programVersion = cfgVersion; } public String getProgramVersion() { return programVersion; } public String getLastUsedPalette() { return lastUsedPalette; } public void setLastUsedPalette(String lastUsedPalette) { this.lastUsedPalette = lastUsedPalette; } public String getPdfExportFont() { return pdfExportFont; } public void setPdfExportFont(String pdfExportFont) { this.pdfExportFont = pdfExportFont; } public String getPdfExportFontBold() { return pdfExportFontBold; } public void setPdfExportFontBold(String pdfExportFontBold) { this.pdfExportFontBold = pdfExportFontBold; } public String getPdfExportFontItalic() { return pdfExportFontItalic; } public void setPdfExportFontItalic(String pdfExportFontItalic) { this.pdfExportFontItalic = pdfExportFontItalic; } public String getPdfExportFontBoldItalic() { return pdfExportFontBoldItalic; } public void setPdfExportFontBoldItalic(String pdfExportFontBoldItalic) { this.pdfExportFontBoldItalic = pdfExportFontBoldItalic; } public boolean isCheckForUpdates() { return checkForUpdates; } public void setCheckForUpdates(boolean checkForUpdates) { this.checkForUpdates = checkForUpdates; } public int getPrintPadding() { return printPadding; } public void setPrintPadding(int printPadding) { this.printPadding = printPadding; } public Point getProgram_location() { return program_location; } public void setProgram_location(Point program_location) { this.program_location = program_location; } public Dimension getProgram_size() { return program_size; } public void setProgram_size(Dimension program_size) { this.program_size = program_size; } public int getMail_split_position() { return mail_split_position; } public void setMail_split_position(int mail_split_position) { this.mail_split_position = mail_split_position; } public int getRight_split_position() { return right_split_position; } public void setRight_split_position(int right_split_position) { this.right_split_position = right_split_position; } public int getMain_split_position() { return main_split_position; } public void setMain_split_position(int main_split_position) { this.main_split_position = main_split_position; } public boolean isEnable_custom_elements() { return enable_custom_elements; } public void setEnable_custom_elements(boolean enable_custom_elements) { this.enable_custom_elements = enable_custom_elements; } public boolean isShow_grid() { return show_grid; } public void setShow_grid(boolean show_grid) { this.show_grid = show_grid; } public boolean isStart_maximized() { return start_maximized; } public void setStart_maximized(boolean start_maximized) { this.start_maximized = start_maximized; } public String getDefaultFontFamily() { return defaultFontFamily; } public void setDefaultFontFamily(String defaultFontFamily) { this.defaultFontFamily = defaultFontFamily; } public Integer getDefaultFontsize() { return defaultFontsize; } public void setDefaultFontsize(Integer defaultFontsize) { this.defaultFontsize = defaultFontsize; } public Integer getPropertiesPanelFontsize() { return propertiesPanelFontsize; } public void setPropertiesPanelFontsize(Integer propertiesPanelFontsize) { this.propertiesPanelFontsize = propertiesPanelFontsize; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/ConfigClassGen.java0000644000175000017500000000361512533641120026210 0ustar benbenpackage com.baselet.control.config; import com.baselet.control.enums.generator.FieldOptions; import com.baselet.control.enums.generator.MethodOptions; import com.baselet.control.enums.generator.SignatureOptions; import com.baselet.control.enums.generator.SortOptions; public class ConfigClassGen { private static final ConfigClassGen instance = new ConfigClassGen(); public static ConfigClassGen getInstance() { return instance; } private ConfigClassGen() {} private boolean generateClassPackage = true; private FieldOptions generateClassFields = FieldOptions.ALL; private MethodOptions generateClassMethods = MethodOptions.ALL; private SignatureOptions generateClassSignatures = SignatureOptions.ALL; private SortOptions generateClassSortings = SortOptions.HEIGHT; public boolean isGenerateClassPackage() { return generateClassPackage; } public void setGenerateClassPackage(boolean generateClassPackage) { this.generateClassPackage = generateClassPackage; } public FieldOptions getGenerateClassFields() { return generateClassFields; } public void setGenerateClassFields(FieldOptions generateClassFields) { this.generateClassFields = generateClassFields; } public MethodOptions getGenerateClassMethods() { return generateClassMethods; } public void setGenerateClassMethods(MethodOptions generateClassMethods) { this.generateClassMethods = generateClassMethods; } public SignatureOptions getGenerateClassSignatures() { return generateClassSignatures; } public void setGenerateClassSignatures(SignatureOptions generateClassSignatures) { this.generateClassSignatures = generateClassSignatures; } public SortOptions getGenerateClassSortings() { return generateClassSortings; } public void setGenerateClassSortings(SortOptions generateClassSortings) { this.generateClassSortings = generateClassSortings; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/DerivedConfig.java0000644000175000017500000000061712533641120026072 0ustar benbenpackage com.baselet.control.config; import java.awt.Font; public class DerivedConfig { public static Font getPanelHeaderFont() { return new Font(Font.SANS_SERIF, Font.BOLD, Config.getInstance().getPropertiesPanelFontsize()); } public static Font getPanelContentFont() { return new Font(Font.MONOSPACED, Font.PLAIN, Config.getInstance().getPropertiesPanelFontsize()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/handler/0000755000175000017500000000000012533641120024130 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/handler/ConfigHandler.java0000644000175000017500000003606612533641120027511 0ustar benbenpackage com.baselet.control.config.handler; import java.awt.Frame; import java.awt.Point; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Properties; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.config.Config; import com.baselet.control.config.ConfigClassGen; import com.baselet.control.config.ConfigMail; import com.baselet.control.config.SharedConfig; import com.baselet.control.enums.Program; import com.baselet.control.enums.generator.FieldOptions; import com.baselet.control.enums.generator.MethodOptions; import com.baselet.control.enums.generator.SignatureOptions; import com.baselet.control.enums.generator.SortOptions; import com.baselet.control.util.Path; import com.baselet.control.util.RecentlyUsedFilesList; import com.baselet.control.util.Utils; import com.baselet.gui.BaseGUI; import com.baselet.gui.standalone.StandaloneGUI; public class ConfigHandler { private static final String PROGRAM_VERSION = "program_version"; private static final String PROPERTIES_PANEL_FONTSIZE = "properties_panel_fontsize"; private static final String DEFAULT_FONTSIZE = "default_fontsize"; private static final String DEFAULT_FONTFAMILY = "default_fontfamily"; private static final String SHOW_STICKINGPOLYGON = "show_stickingpolygon"; private static final String SHOW_GRID = "show_grid"; private static final String ENABLE_CUSTOM_ELEMENTS = "enable_custom_elements"; private static final String UI_MANAGER = "ui_manager"; private static final String PRINT_PADDING = "print_padding"; private static final String PDF_EXPORT_FONT = "pdf_export_font"; private static final String PDF_EXPORT_FONT_BOLD = "pdf_export_font_bold"; private static final String PDF_EXPORT_FONT_ITALIC = "pdf_export_font_italic"; private static final String PDF_EXPORT_FONT_BOLDITALIC = "pdf_export_font_bolditalic"; private static final String CHECK_FOR_UPDATES = "check_for_updates"; private static final String OPEN_FILE_HOME = "open_file_home"; private static final String SAVE_FILE_HOME = "save_file_home"; private static final String DEV_MODE = "dev_mode"; private static final String LAST_USED_PALETTE = "last_used_palette"; private static final String MAIN_SPLIT_POSITION = "main_split_position"; private static final String RIGHT_SPLIT_POSITION = "right_split_position"; private static final String START_MAXIMIZED = "start_maximized"; private static final String MAIL_SPLIT_POSITION = "mail_split_position"; private static final String PROGRAM_SIZE = "program_size"; private static final String PROGRAM_LOCATION = "program_location"; private static final String RECENT_FILES = "recent_files"; private static final String MAIL_SMTP = "mail_smtp"; private static final String MAIL_SMTP_AUTH = "mail_smtp_auth"; private static final String MAIL_SMTP_USER = "mail_smtp_user"; private static final String MAIL_SMTP_PW_STORE = "mail_smtp_pw_store"; private static final String MAIL_SMTP_PW = "mail_smtp_pw"; private static final String MAIL_FROM = "mail_from"; private static final String MAIL_TO = "mail_to"; private static final String MAIL_CC = "mail_cc"; private static final String MAIL_BCC = "mail_bcc"; private static final String MAIL_XML = "mail_xml"; private static final String MAIL_GIF = "mail_gif"; private static final String MAIL_PDF = "mail_pdf"; private static final String GENERATE_CLASS_PACKAGE = "generate_class_package"; private static final String GENERATE_CLASS_FIELDS = "generate_class_fields"; private static final String GENERATE_CLASS_METHODS = "generate_class_methods"; private static final String GENERATE_CLASS_SIGNATURES = "generate_class_signatures"; private static final String GENERATE_CLASS_SORTINGS = "generate_class_sortings"; private static File configfile; private static Properties props; public static void loadConfig() { Config cfg = Config.getInstance(); configfile = new File(Path.config()); if (!configfile.exists()) { return; } props = new Properties(); try { FileInputStream inputStream = new FileInputStream(Path.config()); try { props.load(inputStream); } finally { inputStream.close(); } } catch (Exception ex) { ex.printStackTrace(); } cfg.setProgramVersion(getStringProperty(PROGRAM_VERSION, Program.getInstance().getVersion())); cfg.setDefaultFontsize(getIntProperty(DEFAULT_FONTSIZE, cfg.getDefaultFontsize())); cfg.setPropertiesPanelFontsize(getIntProperty(PROPERTIES_PANEL_FONTSIZE, cfg.getPropertiesPanelFontsize())); cfg.setDefaultFontFamily(getStringProperty(DEFAULT_FONTFAMILY, cfg.getDefaultFontFamily())); SharedConfig.getInstance().setShow_stickingpolygon(getBoolProperty(SHOW_STICKINGPOLYGON, SharedConfig.getInstance().isShow_stickingpolygon())); cfg.setShow_grid(getBoolProperty(SHOW_GRID, cfg.isShow_grid())); cfg.setEnable_custom_elements(getBoolProperty(ENABLE_CUSTOM_ELEMENTS, cfg.isEnable_custom_elements())); cfg.setUiManager(getStringProperty(UI_MANAGER, cfg.getUiManager())); cfg.setPrintPadding(getIntProperty(PRINT_PADDING, cfg.getPrintPadding())); cfg.setPdfExportFont(getStringProperty(PDF_EXPORT_FONT, cfg.getPdfExportFont())); cfg.setPdfExportFontBold(getStringProperty(PDF_EXPORT_FONT_BOLD, cfg.getPdfExportFontBold())); cfg.setPdfExportFontItalic(getStringProperty(PDF_EXPORT_FONT_ITALIC, cfg.getPdfExportFontItalic())); cfg.setPdfExportFontBoldItalic(getStringProperty(PDF_EXPORT_FONT_BOLDITALIC, cfg.getPdfExportFontBoldItalic())); cfg.setCheckForUpdates(getBoolProperty(CHECK_FOR_UPDATES, cfg.isCheckForUpdates())); cfg.setOpenFileHome(getStringProperty(OPEN_FILE_HOME, cfg.getOpenFileHome())); cfg.setSaveFileHome(getStringProperty(SAVE_FILE_HOME, cfg.getSaveFileHome())); SharedConfig.getInstance().setDev_mode(getBoolProperty(DEV_MODE, SharedConfig.getInstance().isDev_mode())); cfg.setLastUsedPalette(getStringProperty(LAST_USED_PALETTE, cfg.getLastUsedPalette())); cfg.setMain_split_position(getIntProperty(MAIN_SPLIT_POSITION, cfg.getMain_split_position())); cfg.setRight_split_position(getIntProperty(RIGHT_SPLIT_POSITION, cfg.getRight_split_position())); cfg.setMail_split_position(getIntProperty(MAIL_SPLIT_POSITION, cfg.getMail_split_position())); cfg.setStart_maximized(getBoolProperty(START_MAXIMIZED, cfg.isStart_maximized())); // In case of start_maximized=true we don't store any size or location information if (!cfg.isStart_maximized()) { cfg.setProgram_size(getDimensionProperty(PROGRAM_SIZE, cfg.getProgram_size())); cfg.setProgram_location(getPointProperty(PROGRAM_LOCATION, cfg.getProgram_location())); } String recentFiles = props.getProperty(RECENT_FILES); if (recentFiles != null) { RecentlyUsedFilesList.getInstance().addAll(Arrays.asList(props.getProperty(RECENT_FILES).split("\\|"))); } /* Mail */ ConfigMail cfgMail = ConfigMail.getInstance(); cfgMail.setMail_smtp(getStringProperty(MAIL_SMTP, cfgMail.getMail_smtp())); cfgMail.setMail_smtp_auth(getBoolProperty(MAIL_SMTP_AUTH, cfgMail.isMail_smtp_auth())); cfgMail.setMail_smtp_user(getStringProperty(MAIL_SMTP_USER, cfgMail.getMail_smtp_user())); cfgMail.setMail_smtp_pw_store(getBoolProperty(MAIL_SMTP_PW_STORE, cfgMail.isMail_smtp_pw_store())); cfgMail.setMail_smtp_pw(getStringProperty(MAIL_SMTP_PW, cfgMail.getMail_smtp_pw())); cfgMail.setMail_from(getStringProperty(MAIL_FROM, cfgMail.getMail_from())); cfgMail.setMail_to(getStringProperty(MAIL_TO, cfgMail.getMail_to())); cfgMail.setMail_cc(getStringProperty(MAIL_CC, cfgMail.getMail_cc())); cfgMail.setMail_bcc(getStringProperty(MAIL_BCC, cfgMail.getMail_bcc())); cfgMail.setMail_xml(getBoolProperty(MAIL_XML, cfgMail.isMail_xml())); cfgMail.setMail_gif(getBoolProperty(MAIL_GIF, cfgMail.isMail_gif())); cfgMail.setMail_pdf(getBoolProperty(MAIL_PDF, cfgMail.isMail_pdf())); /* Generate Class Element Options */ ConfigClassGen genCfg = ConfigClassGen.getInstance(); genCfg.setGenerateClassPackage(getBoolProperty(GENERATE_CLASS_PACKAGE, genCfg.isGenerateClassPackage())); genCfg.setGenerateClassFields(FieldOptions.getEnum(getStringProperty(GENERATE_CLASS_FIELDS, genCfg.getGenerateClassFields().toString()))); genCfg.setGenerateClassMethods(MethodOptions.getEnum(getStringProperty(GENERATE_CLASS_METHODS, genCfg.getGenerateClassMethods().toString()))); genCfg.setGenerateClassSignatures(SignatureOptions.getEnum(getStringProperty(GENERATE_CLASS_SIGNATURES, genCfg.getGenerateClassSignatures().toString()))); genCfg.setGenerateClassSortings(SortOptions.getEnum(getStringProperty(GENERATE_CLASS_SORTINGS, genCfg.getGenerateClassSortings().toString()))); } public static void saveConfig(BaseGUI gui) { Config cfg = Config.getInstance(); if (configfile == null) { return; } try { Utils.safeDeleteFile(configfile, false); Utils.safeCreateFile(configfile, false); Properties props = new Properties(); props.setProperty(PROGRAM_VERSION, Program.getInstance().getVersion()); props.setProperty(DEFAULT_FONTSIZE, Integer.toString(cfg.getDefaultFontsize())); props.setProperty(PROPERTIES_PANEL_FONTSIZE, Integer.toString(cfg.getPropertiesPanelFontsize())); props.setProperty(DEFAULT_FONTFAMILY, cfg.getDefaultFontFamily()); props.setProperty(SHOW_STICKINGPOLYGON, Boolean.toString(SharedConfig.getInstance().isShow_stickingpolygon())); props.setProperty(SHOW_GRID, Boolean.toString(cfg.isShow_grid())); props.setProperty(ENABLE_CUSTOM_ELEMENTS, Boolean.toString(cfg.isEnable_custom_elements())); props.setProperty(UI_MANAGER, cfg.getUiManager()); props.setProperty(PRINT_PADDING, Integer.toString(cfg.getPrintPadding())); props.setProperty(PDF_EXPORT_FONT, cfg.getPdfExportFont()); props.setProperty(PDF_EXPORT_FONT_BOLD, cfg.getPdfExportFontBold()); props.setProperty(PDF_EXPORT_FONT_ITALIC, cfg.getPdfExportFontItalic()); props.setProperty(PDF_EXPORT_FONT_BOLDITALIC, cfg.getPdfExportFontBoldItalic()); props.setProperty(CHECK_FOR_UPDATES, Boolean.toString(cfg.isCheckForUpdates())); props.setProperty(OPEN_FILE_HOME, cfg.getOpenFileHome()); props.setProperty(SAVE_FILE_HOME, cfg.getSaveFileHome()); props.setProperty(DEV_MODE, Boolean.toString(SharedConfig.getInstance().isDev_mode())); props.setProperty(LAST_USED_PALETTE, cfg.getLastUsedPalette()); props.setProperty(MAIN_SPLIT_POSITION, Integer.toString(gui.getMainSplitPosition())); props.setProperty(RIGHT_SPLIT_POSITION, Integer.toString(gui.getRightSplitPosition())); props.setProperty(MAIL_SPLIT_POSITION, Integer.toString(gui.getMailSplitPosition())); if (gui instanceof StandaloneGUI) { // If the window is maximized in any direction this fact is written in the cfg Frame topContainer = ((StandaloneGUI) gui).getMainFrame(); if ((topContainer.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) { props.setProperty(START_MAXIMIZED, "true"); } // Otherwise the size and the location is written in the cfg else { props.setProperty(START_MAXIMIZED, "false"); props.setProperty(PROGRAM_SIZE, topContainer.getSize().width + "," + topContainer.getSize().height); props.setProperty(PROGRAM_LOCATION, topContainer.getLocation().x + "," + topContainer.getLocation().y); } } if (!RecentlyUsedFilesList.getInstance().isEmpty()) { StringBuilder sb = new StringBuilder(""); for (String recentFile : RecentlyUsedFilesList.getInstance()) { sb.append(recentFile).append("|"); } sb.setLength(sb.length() - 1); props.setProperty(RECENT_FILES, sb.toString()); } /* MAIL */ ConfigMail cfgMail = ConfigMail.getInstance(); if (!!cfgMail.getMail_smtp().isEmpty()) { props.setProperty(MAIL_SMTP, cfgMail.getMail_smtp()); } props.setProperty(MAIL_SMTP_AUTH, Boolean.toString(cfgMail.isMail_smtp_auth())); if (!cfgMail.getMail_smtp_user().isEmpty()) { props.setProperty(MAIL_SMTP_USER, cfgMail.getMail_smtp_user()); } props.setProperty(MAIL_SMTP_PW_STORE, Boolean.toString(cfgMail.isMail_smtp_pw_store())); if (!cfgMail.getMail_smtp_pw().isEmpty()) { props.setProperty(MAIL_SMTP_PW, cfgMail.getMail_smtp_pw()); } if (!cfgMail.getMail_from().isEmpty()) { props.setProperty(MAIL_FROM, cfgMail.getMail_from()); } if (!cfgMail.getMail_to().isEmpty()) { props.setProperty(MAIL_TO, cfgMail.getMail_to()); } if (!cfgMail.getMail_cc().isEmpty()) { props.setProperty(MAIL_CC, cfgMail.getMail_cc()); } if (!cfgMail.getMail_bcc().isEmpty()) { props.setProperty(MAIL_BCC, cfgMail.getMail_bcc()); } props.setProperty(MAIL_XML, Boolean.toString(cfgMail.isMail_xml())); props.setProperty(MAIL_GIF, Boolean.toString(cfgMail.isMail_gif())); props.setProperty(MAIL_PDF, Boolean.toString(cfgMail.isMail_pdf())); /* Generate Class Element Options */ ConfigClassGen genCfg = ConfigClassGen.getInstance(); props.setProperty(GENERATE_CLASS_PACKAGE, Boolean.toString(genCfg.isGenerateClassPackage())); props.setProperty(GENERATE_CLASS_FIELDS, genCfg.getGenerateClassFields().toString()); props.setProperty(GENERATE_CLASS_METHODS, genCfg.getGenerateClassMethods().toString()); props.setProperty(GENERATE_CLASS_SIGNATURES, genCfg.getGenerateClassSignatures().toString()); props.setProperty(GENERATE_CLASS_SORTINGS, genCfg.getGenerateClassSortings().toString()); FileOutputStream outStream = new FileOutputStream(configfile); try { props.store(outStream, null); } finally { outStream.close(); } } catch (IOException ex) { ex.printStackTrace(); } } private static int getIntProperty(String key, int defaultValue) { String result = props.getProperty(key); if (result != null) { try { return Integer.parseInt(result); } catch (NumberFormatException e) { e.printStackTrace(); } } return defaultValue; } private static boolean getBoolProperty(String key, boolean defaultValue) { String result = props.getProperty(key); if (result != null) { return Boolean.parseBoolean(result); } return defaultValue; } private static String getStringProperty(String key, String defaultValue) { return props.getProperty(key, defaultValue); } private static Dimension getDimensionProperty(String key, Dimension defaultValue) { String result = props.getProperty(key); if (result != null) { try { int x = Integer.parseInt(result.substring(0, result.indexOf(","))); int y = Integer.parseInt(result.substring(result.indexOf(",") + 1)); return new Dimension(x, y); } catch (NumberFormatException e) { e.printStackTrace(); } } return defaultValue; } private static Point getPointProperty(String key, Point defaultValue) { String result = props.getProperty(key); if (result != null) { try { int x = Integer.parseInt(result.substring(0, result.indexOf(","))); int y = Integer.parseInt(result.substring(result.indexOf(",") + 1)); return new Point(x, y); } catch (NumberFormatException e) { e.printStackTrace(); } } return defaultValue; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/config/ConfigMail.java0000644000175000017500000000465412533641120025377 0ustar benbenpackage com.baselet.control.config; public class ConfigMail { private static final ConfigMail instance = new ConfigMail(); public static ConfigMail getInstance() { return instance; } private String mail_smtp = ""; private boolean mail_smtp_auth = false; private String mail_smtp_user = ""; private boolean mail_smtp_pw_store = false; private String mail_smtp_pw = ""; private String mail_from = ""; private String mail_to = ""; private String mail_cc = ""; private String mail_bcc = ""; private boolean mail_xml = true; private boolean mail_gif = true; private boolean mail_pdf = false; private ConfigMail() {} public String getMail_smtp() { return mail_smtp; } public void setMail_smtp(String mail_smtp) { this.mail_smtp = mail_smtp; } public boolean isMail_smtp_auth() { return mail_smtp_auth; } public void setMail_smtp_auth(boolean mail_smtp_auth) { this.mail_smtp_auth = mail_smtp_auth; } public String getMail_smtp_user() { return mail_smtp_user; } public void setMail_smtp_user(String mail_smtp_user) { this.mail_smtp_user = mail_smtp_user; } public boolean isMail_smtp_pw_store() { return mail_smtp_pw_store; } public void setMail_smtp_pw_store(boolean mail_smtp_pw_store) { this.mail_smtp_pw_store = mail_smtp_pw_store; } public String getMail_smtp_pw() { return mail_smtp_pw; } public void setMail_smtp_pw(String mail_smtp_pw) { this.mail_smtp_pw = mail_smtp_pw; } public String getMail_from() { return mail_from; } public void setMail_from(String mail_from) { this.mail_from = mail_from; } public String getMail_to() { return mail_to; } public void setMail_to(String mail_to) { this.mail_to = mail_to; } public String getMail_cc() { return mail_cc; } public void setMail_cc(String mail_cc) { this.mail_cc = mail_cc; } public String getMail_bcc() { return mail_bcc; } public void setMail_bcc(String mail_bcc) { this.mail_bcc = mail_bcc; } public boolean isMail_xml() { return mail_xml; } public void setMail_xml(boolean mail_xml) { this.mail_xml = mail_xml; } public boolean isMail_gif() { return mail_gif; } public void setMail_gif(boolean mail_gif) { this.mail_gif = mail_gif; } public boolean isMail_pdf() { return mail_pdf; } public void setMail_pdf(boolean mail_pdf) { this.mail_pdf = mail_pdf; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/0000755000175000017500000000000012533641120022375 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/Metakey.java0000644000175000017500000000123312533641120024636 0ustar benbenpackage com.baselet.control.enums; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; public enum Metakey { CTRL, CMD; @Override public String toString() { if (this == CTRL) { return "Ctrl"; } else { return "Cmd"; } } // Use these masks as modifiers if you want to enforce ctrl or meta in addition to a keyevent public int getMask() { if (this == CTRL) { return ActionEvent.CTRL_MASK; } else { return ActionEvent.META_MASK; } } public int getMaskDown() { if (this == CTRL) { return InputEvent.CTRL_DOWN_MASK; } else { return InputEvent.META_DOWN_MASK; } } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/Os.java0000644000175000017500000000013612533641120023621 0ustar benbenpackage com.baselet.control.enums; public enum Os { WINDOWS, LINUX, UNIX, MAC, UNKNOWN }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/generator/0000755000175000017500000000000012533641120024363 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/generator/SortOptions.java0000644000175000017500000000101412533641120027525 0ustar benbenpackage com.baselet.control.enums.generator; public enum SortOptions { HEIGHT("by size"), PACKAGE("by package"), ALPHABET("alphabetically"), RELATIONS("with relations"); private final String label; private SortOptions(String label) { this.label = label; } @Override public String toString() { return label; } public static SortOptions getEnum(String text) { for (SortOptions value : values()) { if (value.toString().equals(text)) { return value; } } return null; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/generator/MethodOptions.java0000644000175000017500000000074212533641120030025 0ustar benbenpackage com.baselet.control.enums.generator; public enum MethodOptions { ALL("all"), NONE("none"), PUBLIC("public only"); private final String label; private MethodOptions(String label) { this.label = label; } @Override public String toString() { return label; } public static MethodOptions getEnum(String text) { for (MethodOptions value : values()) { if (value.toString().equals(text)) { return value; } } return null; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/generator/SignatureOptions.java0000644000175000017500000000101212533641120030535 0ustar benbenpackage com.baselet.control.enums.generator; public enum SignatureOptions { ALL("all"), PARAMS_ONLY("parameters only"), RETURN_ONLY("return type only"); private final String label; private SignatureOptions(String label) { this.label = label; } @Override public String toString() { return label; } public static SignatureOptions getEnum(String text) { for (SignatureOptions value : values()) { if (value.toString().equals(text)) { return value; } } return null; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/control/enums/generator/FieldOptions.java0000644000175000017500000000073412533641120027631 0ustar benbenpackage com.baselet.control.enums.generator; public enum FieldOptions { ALL("all"), NONE("none"), PUBLIC("public only"); private final String label; private FieldOptions(String label) { this.label = label; } @Override public String toString() { return label; } public static FieldOptions getEnum(String text) { for (FieldOptions value : values()) { if (value.toString().equals(text)) { return value; } } return null; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/0000755000175000017500000000000012533641120020352 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/BaseGUI.java0000644000175000017500000001264512533641120022444 0ustar benbenpackage com.baselet.gui; import java.awt.Color; import java.awt.Cursor; import java.awt.Frame; import java.util.Collection; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.UIManager; import javax.swing.plaf.InsetsUIResource; import org.apache.log4j.Logger; import com.baselet.control.CanCloseProgram; import com.baselet.control.Main; import com.baselet.control.config.Config; import com.baselet.diagram.CustomPreviewHandler; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElement; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.menu.MenuFactorySwing; import com.baselet.gui.pane.OwnSyntaxPane; public abstract class BaseGUI { private static final Logger log = Logger.getLogger(BaseGUI.class); protected CanCloseProgram main; protected Collection selected_elements; protected boolean paletteEdited = false; public BaseGUI(CanCloseProgram main) { this.main = main; } public final void initGUI() { try { UIManager.setLookAndFeel(Config.getInstance().getUiManager()); } catch (Exception e) { // If the LookAndFeel cannot be set, it gets logged (without stacktrace) and the default style is used log.error(e.getMessage()); } initGUIParameters(); // this.setLayout(new BorderLayout()); init(); // this.requestFocus(); } public abstract void focusPropertyPane(); public JPopupMenu getContextMenu(GridElement e) { MenuFactorySwing menuFactory = MenuFactorySwing.getInstance(); JPopupMenu contextMenu = new JPopupMenu(); if (e instanceof CustomElement) { contextMenu.add(menuFactory.createEditSelected()); } if (!(Main.getHandlerForElement(e) instanceof CustomPreviewHandler)) { contextMenu.add(menuFactory.createDelete()); contextMenu.add(menuFactory.createCopy()); contextMenu.add(menuFactory.createCut()); } JMenuItem group = menuFactory.createGroup(); contextMenu.add(group); if (selected_elements.size() < 2) { group.setEnabled(false); } JMenuItem ungroup = menuFactory.createUngroup(); contextMenu.add(ungroup); if (e.getGroup() == null) { ungroup.setEnabled(false); } contextMenu.add(menuFactory.createSetColor(true)); contextMenu.add(menuFactory.createSetColor(false)); contextMenu.add(createAlignmentMenu(menuFactory)); contextMenu.add(createLayerMenu(menuFactory)); return contextMenu; } private JMenu createLayerMenu(MenuFactorySwing menuFactory) { JMenu layerMenu = menuFactory.createLayerUp(); layerMenu.setEnabled(!selected_elements.isEmpty()); return layerMenu; } private JMenu createAlignmentMenu(MenuFactorySwing menuFactory) { JMenu alignmentMenu = menuFactory.createAlign(); alignmentMenu.setEnabled(selected_elements.size() > 1); // only enable when at least 2 elements are selected return alignmentMenu; } public void elementsSelected(Collection selectedElements) { selected_elements = selectedElements; } protected void initGUIParameters() { UIManager.put("TabbedPane.selected", Color.white); UIManager.put("TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 0)); UIManager.put("TabbedPane.contentBorderInsets", new InsetsUIResource(0, 0, 0, 0)); } public void setPaletteEdited(boolean isEdited) { paletteEdited = isEdited; } public boolean getPaletteEdited() { return paletteEdited; } public abstract CustomElementHandler getCurrentCustomHandler(); public abstract void setCustomPanelEnabled(boolean enable); public abstract void setMailPanelEnabled(boolean enable); public abstract boolean isMailPanelVisible(); public abstract void updateDiagramName(DiagramHandler diagram, String name); public abstract void setDiagramChanged(DiagramHandler diagram, boolean changed); public abstract void setCustomElementChanged(CustomElementHandler handler, boolean changed); public abstract void closeWindow(); protected abstract void init(); public abstract String getSelectedPalette(); public void showPalette(String palette) { Config.getInstance().setLastUsedPalette(palette); } public abstract void open(DiagramHandler diagram); public abstract void jumpTo(DiagramHandler diagram); public abstract void close(DiagramHandler diagram); public abstract DrawPanel getCurrentDiagram(); public abstract void enablePasteMenuEntry(); public abstract void setCustomElementSelected(boolean selected); public abstract void diagramSelected(DiagramHandler handler); public void enableSearch(@SuppressWarnings("unused") boolean enable) { /* do nothing */ } public abstract int getMainSplitPosition(); public abstract int getMailSplitPosition(); public abstract int getRightSplitPosition(); public abstract OwnSyntaxPane getPropertyPane(); public abstract void setValueOfZoomDisplay(int i); public void afterSaving() { /* do nothing */ } public abstract void setCursor(Cursor cursor); public abstract void requestFocus(); public void updateGrayedOutMenuItems(@SuppressWarnings("unused") DiagramHandler handler) { /* do nothing */ } public abstract Frame getMainFrame(); public void setLookAndFeel(String newui, JFrame optionframe) { /* do nothing */ } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/BaseGUIBuilder.java0000644000175000017500000001762212533641120023753 0ustar benbenpackage com.baselet.gui; import java.awt.CardLayout; import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.plaf.basic.BasicSplitPaneUI; import com.baselet.control.Main; import com.baselet.control.config.Config; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.custom.CustomElementPanel; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.PaletteHandler; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.listener.DividerListener; import com.baselet.gui.listener.PaletteComboBoxListener; import com.baselet.gui.listener.PropertyPanelListener; import com.baselet.gui.pane.OwnSyntaxPane; public abstract class BaseGUIBuilder { private JPanel palettePanel; private CardLayout palettePanelLayout; private JSplitPane rightSplit; private JComboBox paletteList; private CustomElementHandler customHandler; private JSplitPane mainSplit; private MailPanel mailPanel; private JSplitPane customSplit; private JSplitPane mailSplit; private JPanel rightPanel; private OwnSyntaxPane propertyTextPane; protected JSplitPane initBase(Component mainComponent, final int mainDividerLoc) { propertyTextPane = createPropertyTextPane(); // must be initialized before palettePanel because it could be accessed during palette initialization (eg in case of different default fontsize) palettePanel = newPalettePanel(); rightSplit = newGenericSplitPane(JSplitPane.VERTICAL_SPLIT, palettePanel, propertyTextPane.getPanel(), 2, Config.getInstance().getRight_split_position(), true); rightPanel = newRightPanel(); mainSplit = newGenericSplitPane(JSplitPane.HORIZONTAL_SPLIT, mainComponent, rightPanel, 2, mainDividerLoc, true); // hide mainSplit on doubleclick ((BasicSplitPaneUI) mainSplit.getUI()).getDivider().addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { rightPanel.setVisible(!rightPanel.isVisible()); mainSplit.setDividerLocation(mainDividerLoc); } } }); customHandler = new CustomElementHandler(); customHandler.getPanel().setVisible(false); customSplit = newGenericSplitPane(JSplitPane.VERTICAL_SPLIT, mainSplit, getCustomPanel(), 0, 0, true); mailPanel = new MailPanel(); mailPanel.setVisible(false); mailSplit = newGenericSplitPane(JSplitPane.VERTICAL_SPLIT, mailPanel, customSplit, 0, 0, true); return mailSplit; } public JSplitPane getMailSplit() { return mailSplit; } public JSplitPane getCustomSplit() { return customSplit; } public MailPanel getMailPanel() { return mailPanel; } public JSplitPane getMainSplit() { return mainSplit; } public JPanel getPalettePanel() { return palettePanel; } public JComboBox getPaletteList() { return paletteList; } public JSplitPane getRightSplit() { return rightSplit; } public CustomElementHandler getCustomHandler() { return customHandler; } public CustomElementPanel getCustomPanel() { return customHandler.getPanel(); } public JPanel newPalettePanel() { palettePanelLayout = new CardLayout(); JPanel palettePanel = new JPanel(palettePanelLayout); palettePanel.addComponentListener(new DividerListener()); // Adding the DividerListener which refreshes Scrollbars here is enough for all dividers for (PaletteHandler palette : Main.getInstance().getPalettes().values()) { palettePanel.add(palette.getDrawPanel().getScrollPane(), palette.getName()); } return palettePanel; } public JSplitPane newGenericSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent, int dividerSize, int dividerLocation, boolean visible) { JSplitPane pane = new JSplitPane(newOrientation, newLeftComponent, newRightComponent); pane.setDividerSize(dividerSize); pane.setDividerLocation(dividerLocation); pane.setResizeWeight(1); pane.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 0)); pane.setAlignmentX(Component.RIGHT_ALIGNMENT); pane.setVisible(visible); return pane; } private JPanel newRightPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); rightSplit.setAlignmentX(Component.CENTER_ALIGNMENT); panel.add(newPaletteControlsPanel()); panel.add(rightSplit); return panel; } private JPanel newPaletteControlsPanel() { createPaletteList(); JPanel paletteControlsPanel = new JPanel(); paletteControlsPanel.setLayout(new BoxLayout(paletteControlsPanel, BoxLayout.X_AXIS)); paletteControlsPanel.add(paletteList); return paletteControlsPanel; } public void createPaletteList() { paletteList = new JComboBox(); paletteList.setMaximumRowCount(15); paletteList.setAlignmentX(Component.CENTER_ALIGNMENT); for (PaletteHandler palette : Main.getInstance().getPalettes().values()) { paletteList.addItem(palette.getName()); } PaletteComboBoxListener pl = new PaletteComboBoxListener(); paletteList.addActionListener(pl); // add listeners after adding every paletteList entry to avoid triggering the listener everytime paletteList.addMouseWheelListener(pl); // only set last used palette if the program version has not changed and if lastUsedPalette is not null (if the version is not equal or the lastUsedPalette String is invalid it will simply stay at index 0; null must not be set because it invalidates the selectionstate instead of setting it to 0; see Issue 215) String lastUsedPalette = Config.getInstance().getLastUsedPalette(); if (Program.getInstance().getVersion().equals(Config.getInstance().getProgramVersion()) && lastUsedPalette != null) { paletteList.setSelectedItem(lastUsedPalette); } } private OwnSyntaxPane createPropertyTextPane() { OwnSyntaxPane propertyTextPane = new OwnSyntaxPane(); PropertyPanelListener pListener = new PropertyPanelListener(); propertyTextPane.getTextComponent().addKeyListener(pListener); propertyTextPane.getTextComponent().getDocument().addDocumentListener(pListener); return propertyTextPane; } public OwnSyntaxPane getPropertyTextPane() { return propertyTextPane; } public void setMailPanelEnabled(boolean enable) { getMailPanel().setVisible(enable); if (enable) { int mailDividerLoc = Math.max(Constants.MIN_MAIL_SPLITPANEL_SIZE, Config.getInstance().getMail_split_position()); mailSplit.setDividerLocation(mailDividerLoc); mailSplit.setDividerSize(2); } else { mailSplit.setDividerSize(0); } } public void setCustomPanelEnabled(boolean enable) { CustomElementPanel customPanel = getCustomPanel(); if (customPanel.isVisible() != enable) { int loc = getMainSplit().getDividerLocation(); customPanel.setVisible(enable); if (enable) { int rightloc = getRightSplit().getDividerLocation(); getCustomSplit().setDividerSize(2); getRightSplit().setDividerSize(0); customPanel.getLeftSplit().setLeftComponent(propertyTextPane.getPanel()); getCustomSplit().setDividerLocation(rightloc); customPanel.getRightSplit().setDividerLocation(loc); customPanel.getLeftSplit().setDividerLocation(CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().getWidth() / 2); customPanel.getLeftSplit().updateUI(); } else { int rightloc = getCustomSplit().getDividerLocation(); getCustomSplit().setDividerSize(0); getRightSplit().setDividerSize(2); getRightSplit().setRightComponent(propertyTextPane.getPanel()); getRightSplit().setDividerLocation(rightloc); } getMainSplit().setDividerLocation(loc); } } public void setPaletteActive(String paletteName) { palettePanelLayout.show(palettePanel, paletteName); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/OptionPanel.java0000644000175000017500000001623412533641120023453 0ustar benbenpackage com.baselet.gui; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager.LookAndFeelInfo; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.config.Config; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; import com.baselet.diagram.DiagramHandler; @SuppressWarnings("serial") public class OptionPanel extends JPanel implements ActionListener { private final Logger log = Logger.getLogger(OptionPanel.class); private static OptionPanel optionpanel; public static OptionPanel getInstance() { if (optionpanel == null) { optionpanel = new OptionPanel(); } return optionpanel; } private final JFrame optionframe; private final JCheckBox show_stickingpolygon = new JCheckBox(); private final JCheckBox show_grid = new JCheckBox(); private final JCheckBox enable_custom_elements = new JCheckBox(); private final JCheckBox checkForUpdates = new JCheckBox(); private final JCheckBox developerMode = new JCheckBox(); private final JComboBox ui_manager; private final JComboBox default_fontsize = new JComboBox(new Integer[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }); private final JComboBox propertiesPanelFontsize = new JComboBox(new Integer[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }); private final JComboBox default_fontfamily = new JComboBox(Constants.fontFamilyList.toArray(new String[Constants.fontFamilyList.size()])); private final Vector uis_technicalNames = new Vector(); private OptionPanel() { setLayout(new GridLayout(0, 2, 4, 4)); setAlignmentX(Component.LEFT_ALIGNMENT); Vector uis_humanReadableNameVector = new Vector(); LookAndFeelInfo[] lookAndFeelInfoArray = Constants.lookAndFeels.toArray(new LookAndFeelInfo[Constants.lookAndFeels.size()]); for (LookAndFeelInfo info : lookAndFeelInfoArray) { uis_technicalNames.add(info.getClassName()); uis_humanReadableNameVector.add(info.getName()); } ui_manager = new JComboBox(uis_humanReadableNameVector); this.add(new JLabel("Show sticking ploygon")); this.add(show_stickingpolygon); this.add(new JLabel("Show grid")); this.add(show_grid); this.add(new JLabel("Enable Custom Elements")); this.add(enable_custom_elements); this.add(new JLabel("Check for " + Program.getInstance().getProgramName() + " updates")); this.add(checkForUpdates); if (Program.getInstance().getRuntimeType() == RuntimeType.STANDALONE) { this.add(new JLabel(Program.getInstance().getProgramName() + " style")); this.add(ui_manager); } this.add(new JLabel("Default fontsize")); this.add(default_fontsize); this.add(new JLabel("Properties panel fontsize (requires restart)")); this.add(propertiesPanelFontsize); this.add(new JLabel("Default fontfamily")); this.add(default_fontfamily); this.add(new JLabel("Developer Mode (show extended Element Info)")); this.add(developerMode); JButton button_ok = new JButton("Ok"); button_ok.setActionCommand("Ok"); button_ok.addActionListener(this); JButton button_cancel = new JButton("Cancel"); button_cancel.setActionCommand("Cancel"); button_cancel.addActionListener(this); JPanel button_panel = new JPanel(); button_panel.setLayout(new BoxLayout(button_panel, BoxLayout.X_AXIS)); button_panel.add(Box.createHorizontalGlue()); button_panel.add(button_cancel); button_panel.add(Box.createRigidArea(new Dimension(20, 0))); button_panel.add(button_ok); button_panel.add(Box.createHorizontalGlue()); button_panel.setAlignmentX(Component.LEFT_ALIGNMENT); JPanel parent = new JPanel(); parent.setLayout(new BoxLayout(parent, BoxLayout.Y_AXIS)); parent.add(Box.createRigidArea(new Dimension(10, 10))); parent.add(this); parent.add(Box.createRigidArea(new Dimension(0, 20))); parent.add(button_panel); parent.add(Box.createRigidArea(new Dimension(0, 20))); optionframe = new JFrame(Program.getInstance().getProgramName() + " Options"); optionframe.setContentPane(parent); optionframe.pack(); // autoresize of the optionframe } public void showOptionPanel() { show_stickingpolygon.setSelected(SharedConfig.getInstance().isShow_stickingpolygon()); show_grid.setSelected(Config.getInstance().isShow_grid()); enable_custom_elements.setSelected(Config.getInstance().isEnable_custom_elements()); checkForUpdates.setSelected(Config.getInstance().isCheckForUpdates()); developerMode.setSelected(SharedConfig.getInstance().isDev_mode()); ui_manager.setSelectedIndex(uis_technicalNames.indexOf(Config.getInstance().getUiManager())); default_fontsize.setSelectedItem(Config.getInstance().getDefaultFontsize()); propertiesPanelFontsize.setSelectedItem(Config.getInstance().getPropertiesPanelFontsize()); default_fontfamily.setSelectedItem(Config.getInstance().getDefaultFontFamily()); javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() { optionframe.setLocationRelativeTo(CurrentGui.getInstance().getGui().getMainFrame()); optionframe.setVisible(true); optionframe.toFront(); } }); } private void hideOptionPanel() { optionframe.setVisible(false); } // ok or cancel button pressed @Override public void actionPerformed(ActionEvent ae) { hideOptionPanel(); if (ae.getActionCommand().equals("Ok")) { SharedConfig.getInstance().setShow_stickingpolygon(show_stickingpolygon.isSelected()); Config.getInstance().setShow_grid(show_grid.isSelected()); Config.getInstance().setEnable_custom_elements(enable_custom_elements.isSelected()); Config.getInstance().setCheckForUpdates(checkForUpdates.isSelected()); SharedConfig.getInstance().setDev_mode(developerMode.isSelected()); Config.getInstance().setDefaultFontsize((Integer) default_fontsize.getSelectedItem()); String newui = uis_technicalNames.get(ui_manager.getSelectedIndex()); // only set look and feel if it has changed, because it messes up frame-size if (newui != null && !newui.equals(Config.getInstance().getUiManager())) { Config.getInstance().setUiManager(newui); CurrentGui.getInstance().getGui().setLookAndFeel(newui, optionframe); } // redraw every element to apply changes (like show stickingpolygon, fontsize, ...) for (DiagramHandler d : Main.getInstance().getDiagramsAndPalettes()) { d.getFontHandler().resetFontSize(); d.getDrawPanel().updateElements(); d.getDrawPanel().repaint(); } Config.getInstance().setPropertiesPanelFontsize((Integer) propertiesPanelFontsize.getSelectedItem()); String newfamily = (String) default_fontfamily.getSelectedItem(); Config.getInstance().setDefaultFontFamily(newfamily); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/0000755000175000017500000000000012533641120022177 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/PaletteEntityListener.java0000644000175000017500000001654712533641120027360 0ustar benbenpackage com.baselet.gui.listener; import java.awt.Point; import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Vector; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.Constants; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.ElementFactorySwing; import com.baselet.element.Selector; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.AddElement; import com.baselet.gui.command.Command; public class PaletteEntityListener extends GridElementListener { Map previousDraggingLocation; private static HashMap entitylistener = new HashMap(); private Vector copiedEntities; public static PaletteEntityListener getInstance(DiagramHandler handler) { if (!entitylistener.containsKey(handler)) { entitylistener.put(handler, new PaletteEntityListener(handler)); } return entitylistener.get(handler); } protected PaletteEntityListener(DiagramHandler handler) { super(handler); previousDraggingLocation = new Hashtable(); copiedEntities = new Vector(); } @Override public void mouseDoubleClicked(GridElement me) { selector.deselectAll(); // deselect elements in palette copyEntity(me); } @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); List selectedEntities = handler.getDrawPanel().getSelector().getSelectedElements(); for (GridElement currentEntity : selectedEntities) { if (IS_DRAGGING) { previousDraggingLocation.put(currentEntity, currentEntity.getRectangle()); } } } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); GridElement entity = handler.getDrawPanel().getElementToComponent(me.getComponent()); if (IS_DRAGGED_FROM_PALETTE) { moveDraggedEntities(); } else if (entity.getRectangle().x + entity.getRectangle().width <= 0) { resetEntities(); insertDraggedEntities(me); handler.getDrawPanel().getSelector().deselectAllWithoutUpdatePropertyPanel(); } } private void moveDraggedEntities() { for (GridElement copiedEntity : copiedEntities) { int x = getNewCoordinate().x - getOldCoordinate().x; int y = getNewCoordinate().y - getOldCoordinate().y; x = CurrentDiagram.getInstance().getDiagramHandler().realignToGrid(false, x); y = CurrentDiagram.getInstance().getDiagramHandler().realignToGrid(false, y); copiedEntity.setLocationDifference(x, y); } } private void resetEntities() { List selectedEntities = handler.getDrawPanel().getSelector().getSelectedElements(); for (GridElement currentEntity : selectedEntities) { Rectangle previousLocation = previousDraggingLocation.get(currentEntity); currentEntity.setLocation(previousLocation.x, previousLocation.y); } } private void insertDraggedEntities(MouseEvent me) { GridElement entity = handler.getDrawPanel().getElementToComponent(me.getComponent()); DrawPanel currentDiagram = CurrentGui.getInstance().getGui().getCurrentDiagram(); List selectedEntities = handler.getDrawPanel().getSelector().getSelectedElements(); if (!allowCopyEntity()) { return; } copiedEntities.clear(); // We save the actual zoom level of the diagram and the palette int oldZoomDiagram = currentDiagram.getHandler().getGridSize(); int oldZoomPalette = handler.getGridSize(); // and reset the zoom level of both to default before inserting the new entity (to avoid problems with entity-size) currentDiagram.getHandler().setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); IS_DRAGGING = false; IS_DRAGGED_FROM_PALETTE = true; for (GridElement currentEntity : selectedEntities) { GridElement copiedEntity = copyEntity(currentEntity); copiedEntities.add(copiedEntity); int x = currentEntity.getRectangle().x - entity.getRectangle().x; int y = currentEntity.getRectangle().y - entity.getRectangle().y; x -= entity.getRectangle().width / 2; y -= entity.getRectangle().height / 2; copiedEntity.setLocation(x, y); } Selector.replaceGroupsWithNewGroups(copiedEntities, selector); // After inserting the new entity we restore the old zoom level of both diagrams currentDiagram.getHandler().setGridAndZoom(oldZoomDiagram, false); handler.setGridAndZoom(oldZoomPalette, false); // set entity positions relative to current mouse pointer location on screen updateEntityPositions(me); } private void updateEntityPositions(MouseEvent me) { DiagramHandler currentHandler = CurrentDiagram.getInstance().getDiagramHandler(); Point mousePosition = me.getLocationOnScreen(); int mouseX = mousePosition.x - currentHandler.getDrawPanel().getLocationOnScreen().x; int mouseY = mousePosition.y - currentHandler.getDrawPanel().getLocationOnScreen().y; for (GridElement copiedEntity : copiedEntities) { int x = copiedEntity.getRectangle().x; int y = copiedEntity.getRectangle().y; x += mouseX; y += mouseY; x = CurrentDiagram.getInstance().getDiagramHandler().realignToGrid(false, x); y = CurrentDiagram.getInstance().getDiagramHandler().realignToGrid(false, y); copiedEntity.setLocation(x, y); } } @Override public void mouseReleased(MouseEvent me) { super.mouseReleased(me); CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().updatePanelAndScrollbars(); } protected boolean allowCopyEntity() { return true; } protected GridElement copyEntity(GridElement me) { DrawPanel currentDiagram = CurrentGui.getInstance().getGui().getCurrentDiagram(); // We save the actual zoom level of the diagram and the palette int oldZoomDiagram = currentDiagram.getHandler().getGridSize(); int oldZoomPalette = handler.getGridSize(); // and reset the zoom level of both to default before inserting the new entity (to avoid problems with entity-size) currentDiagram.getHandler().setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); GridElement e = ElementFactorySwing.createCopy(me); e.setProperty(GroupFacet.KEY, null); Command cmd; Point viewp = currentDiagram.getScrollPane().getViewport().getViewPosition(); int upperLeftX = (int) (viewp.getX() - viewp.getX() % oldZoomDiagram); int upperLeftY = (int) (viewp.getY() - viewp.getY() % oldZoomDiagram); cmd = new AddElement(e, handler.realignToGrid((upperLeftX / oldZoomDiagram + Constants.PASTE_DISPLACEMENT_GRIDS) * Constants.DEFAULTGRIDSIZE), handler.realignToGrid((upperLeftY / oldZoomDiagram + Constants.PASTE_DISPLACEMENT_GRIDS) * Constants.DEFAULTGRIDSIZE)); currentDiagram.getHandler().getController().executeCommand(cmd); currentDiagram.getSelector().selectOnly(e); // After inserting the new entity we restore the old zoom level of both diagrams currentDiagram.getHandler().setGridAndZoom(oldZoomDiagram, false); handler.setGridAndZoom(oldZoomPalette, false); return e; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/DiagramListener.java0000644000175000017500000000577112533641120026126 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import javax.swing.JComponent; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.basics.geom.Point; import com.baselet.control.constants.Constants; import com.baselet.control.constants.SystemInfo; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.SelectorFrame; import com.baselet.gui.CurrentGui; public class DiagramListener extends UniversalListener implements MouseWheelListener { private static final Logger log = Logger.getLogger(DiagramListener.class); public DiagramListener(DiagramHandler handler) { super(handler); } @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); // If some elements are selected, and the selector key (ctrl or meta) is still hold, don't deselect all elements if the drawpanel was clicked if (!selector.getSelectedElements().isEmpty() && (me.getModifiers() & SystemInfo.META_KEY.getMask()) != 0) { return; } // deselect elements of all drawpanels selector.deselectAll(); // this call is only necessary in eclipse plugin - TODO refactor and clear issue why this is necessary there for (DiagramHandler h : Main.getInstance().getDiagramsAndPalettes()) { h.getDrawPanel().getSelector().deselectAllWithoutUpdatePropertyPanel(); } selector.updateSelectorInformation(); // after everything is deselected updateSelectorInformation (to update property panel content) if ((me.getModifiers() & SystemInfo.META_KEY.getMask()) != 0) { SelectorFrame selframe = selector.getSelectorFrame(); selframe.setLocation(getOffset(me).getX(), getOffset(me).getY()); selframe.setSize(1, 1); ((JComponent) me.getComponent()).add(selframe, 0); selector.setSelectorFrameActive(true); } } @Override public void mouseMoved(MouseEvent me) { super.mouseMoved(me); CurrentGui.getInstance().getGui().setCursor(Constants.DEFAULT_CURSOR); } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); log.debug("mouseDragged!!"); dragDiagram(); } @Override protected Point getOffset(MouseEvent me) { return new Point(me.getX(), me.getY()); } @Override public void mouseWheelMoved(MouseWheelEvent e) { // Only if Ctrl is pressed while scrolling, we zoom in and out if ((e.getModifiersEx() & SystemInfo.META_KEY.getMaskDown()) == SystemInfo.META_KEY.getMaskDown()) { int actualZoom = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); // e.getWheelRotation is -1 if scrolling up and +1 if scrolling down therefore we subtract it CurrentDiagram.getInstance().getDiagramHandler().setGridAndZoom(actualZoom - e.getWheelRotation()); } else { // otherwise scroll the diagram CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().scroll(e.getWheelRotation()); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/GUIListener.java0000644000175000017500000000672112533641120025202 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Collection; import java.util.Collections; import java.util.Vector; import com.baselet.control.basics.geom.Point; import com.baselet.control.config.SharedConfig; import com.baselet.control.enums.Direction; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.Command; import com.baselet.gui.command.Macro; public class GUIListener implements KeyListener { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SHIFT) { SharedConfig.getInstance().setStickingEnabled(false); } DiagramHandler handler = CurrentDiagram.getInstance().getDiagramHandler(); if (handler != null && !e.isAltDown() && !e.isAltGraphDown() /* && !e.isControlDown() && !e.isMetaDown() */) { /** * Enter: jumps directly into the diagram */ if (e.getKeyCode() == KeyEvent.VK_ENTER) { CurrentGui.getInstance().getGui().focusPropertyPane(); } /** * Ctrl +/-: Zoom diagram by 10% */ // KeyChar check doesn't check non-numpad + on some keyboards, therefore we also need KeyEvent.VK_PLUS else if (e.getKeyChar() == '+' || e.getKeyCode() == KeyEvent.VK_PLUS) { int actualZoom = handler.getGridSize(); handler.setGridAndZoom(actualZoom + 1); } // KeyChar check doesn't check non-numpad - on some keyboards, therefore we also need KeyEvent.VK_MINUS else if (e.getKeyChar() == '-' || e.getKeyCode() == KeyEvent.VK_MINUS) { int actualZoom = handler.getGridSize(); handler.setGridAndZoom(actualZoom - 1); } /** * Cursors: Move diagram by a small distance */ else { int diffx = 0; int diffy = 0; if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_KP_DOWN) { diffy = handler.getGridSize(); } if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_KP_UP) { diffy = -handler.getGridSize(); } if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_KP_LEFT) { diffx = -handler.getGridSize(); } if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_KP_RIGHT) { diffx = handler.getGridSize(); } if (diffx != 0 || diffy != 0) { // Move only selected entities or all if no entity is selected Collection entitiesToBeMoved = handler.getDrawPanel().getSelector().getSelectedElements(); if (entitiesToBeMoved.isEmpty()) { entitiesToBeMoved = handler.getDrawPanel().getGridElements(); } Point opos = getOriginalPos(diffx, diffy, entitiesToBeMoved.iterator().next()); Vector ALL_MOVE_COMMANDS = GridElementListener.calculateFirstMoveCommands(diffx, diffy, opos, entitiesToBeMoved, e.isShiftDown(), true, handler, Collections. emptySet()); handler.getController().executeCommand(new Macro(ALL_MOVE_COMMANDS)); CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().updatePanelAndScrollbars(); } } } } private Point getOriginalPos(int diffx, int diffy, GridElement ge) { return new Point(ge.getRectangle().x - diffx, ge.getRectangle().y - diffy); } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SHIFT) { SharedConfig.getInstance().setStickingEnabled(true); } } @Override public void keyTyped(KeyEvent e) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/ScrollbarListener.java0000644000175000017500000000152712533641120026500 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import com.baselet.diagram.DrawPanel; public class ScrollbarListener implements MouseListener, MouseWheelListener { private DrawPanel drawpanel; public ScrollbarListener(DrawPanel drawpanel) { super(); this.drawpanel = drawpanel; } @Override public void mouseClicked(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) { drawpanel.updatePanelAndScrollbars(); } @Override public void mouseWheelMoved(MouseWheelEvent e) { drawpanel.updatePanelAndScrollbars(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/OldRelationListener.java0000644000175000017500000001517512533641120026775 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.MouseEvent; import java.util.Collections; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.geom.Point; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Direction; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.element.old.element.Relation; import com.baselet.element.sticking.StickableMap; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.Command; import com.baselet.gui.command.Move; import com.baselet.gui.command.OldMoveLinePoint; import com.baselet.gui.command.RemoveElement; /** * new relation doesnt need its own listener */ @Deprecated public class OldRelationListener extends GridElementListener { private static class OldAddLinePoint extends Command { private final Relation _relation; private final int _where; private final int _x; private final int _y; private int getX() { return _x * Main.getHandlerForElement(_relation).getGridSize(); } private int getY() { return _y * Main.getHandlerForElement(_relation).getGridSize(); } public OldAddLinePoint(Relation r, int i, int x, int y) { _relation = r; _where = i; _x = x / Main.getHandlerForElement(_relation).getGridSize(); _y = y / Main.getHandlerForElement(_relation).getGridSize(); } @Override public void execute(DiagramHandler handler) { super.execute(handler); Vector tmp = _relation.getLinePoints(); tmp.insertElementAt(new Point(getX(), getY()), _where); _relation.repaint(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); Vector tmp = _relation.getLinePoints(); tmp.removeElementAt(_where); _relation.repaint(); } } private static class OldRemoveLinePoint extends Command { private final Relation _relation; private final int _where; private final int _x; private final int _y; private int getX() { return _x * Main.getHandlerForElement(_relation).getGridSize(); } private int getY() { return _y * Main.getHandlerForElement(_relation).getGridSize(); } public OldRemoveLinePoint(Relation r, int i) { _relation = r; _where = i; Point p = r.getLinePoints().elementAt(i); _x = p.x / Main.getHandlerForElement(_relation).getGridSize(); _y = p.y / Main.getHandlerForElement(_relation).getGridSize(); } @Override public void execute(DiagramHandler handler) { super.execute(handler); Vector tmp = _relation.getLinePoints(); tmp.removeElementAt(_where); _relation.repaint(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); Vector tmp = _relation.getLinePoints(); tmp.insertElementAt(new Point(getX(), getY()), _where); _relation.repaint(); } } private boolean IS_DRAGGING_LINEPOINT = false; private boolean IS_DRAGGING_LINE = false; private int LINEPOINT = -1; public OldRelationListener(DiagramHandler handler) { super(handler); } @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); if (me.getButton() == MouseEvent.BUTTON1) { IS_DRAGGING = false; Relation rel = (Relation) me.getComponent(); int where = rel.getLinePoint(new Point(me.getX(), me.getY())); if (where >= 0) { IS_DRAGGING_LINEPOINT = true; LINEPOINT = where; } else if (rel.isWholeLine(me.getX(), me.getY())) { IS_DRAGGING_LINE = true; IS_DRAGGING = true; } else if (me.getButton() == MouseEvent.BUTTON2) { IS_DRAGGING_DIAGRAM = true; IS_DRAGGING_LINE = false; IS_DRAGGING_LINEPOINT = false; IS_DRAGGING = false; } } } @Override public void mouseReleased(MouseEvent me) { super.mouseReleased(me); if (IS_DRAGGING_LINEPOINT & LINEPOINT >= 0) { Relation rel = (Relation) me.getComponent(); if (rel.allPointsOnSamePos()) { // If mousebutton is released and all points of a relation are on the same position, // the command which moved all points to the same position gets undone and the relation gets removed instead controller.undo(); controller.executeCommand(new RemoveElement(rel)); } else if (rel.isOnLine(LINEPOINT)) { controller.executeCommand( new OldRemoveLinePoint(rel, LINEPOINT)); } } IS_DRAGGING_LINEPOINT = false; IS_DRAGGING_LINE = false; } @Override public void mouseMoved(MouseEvent me) { super.mouseMoved(me); Relation rel = (Relation) me.getComponent(); int where = rel.getLinePoint(new Point(me.getX(), me.getY())); if (where >= 0) { CurrentGui.getInstance().getGui().setCursor(Constants.HAND_CURSOR); } else if (rel.isWholeLine(me.getX(), me.getY())) { CurrentGui.getInstance().getGui().setCursor(Constants.MOVE_CURSOR); } else { CurrentGui.getInstance().getGui().setCursor(Constants.CROSS_CURSOR); } return; } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); if (disableElementMovement()) { return; } if (IS_DRAGGING) { return; } if (IS_DRAGGING_DIAGRAM) { return; } Relation r = (Relation) me.getComponent(); int gridSize = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); // delta int delta_x = 0; int delta_y = 0; if (IS_DRAGGING_LINEPOINT) { Vector tmp = r.getLinePoints(); Point p = tmp.elementAt(LINEPOINT); delta_x = (r.getRectangle().x + p.x) % gridSize; delta_y = (r.getRectangle().y + p.y) % gridSize; } Point newp = getNewCoordinate(); Point oldp = getOldCoordinate(); int diffx = newp.x - oldp.x - delta_x; int diffy = newp.y - oldp.y - delta_y; if (IS_DRAGGING_LINEPOINT & LINEPOINT >= 0) { controller.executeCommand( new OldMoveLinePoint(r, LINEPOINT, diffx, diffy)); return; } else if (IS_DRAGGING_LINE) { controller.executeCommand(new Move(Collections. emptySet(), r, diffx, diffy, oldp, me.isShiftDown(), false, true, StickableMap.EMPTY_MAP)); return; } int where = r.getLinePoint(new Point(me.getX(), me.getY())); if (where >= 0) { IS_DRAGGING_LINEPOINT = true; LINEPOINT = where; controller.executeCommand( new OldMoveLinePoint(r, where, diffx, diffy)); return; } else { Point p = new Point(me.getX(), me.getY()); int ins = r.getWhereToInsert(p); if (ins > 0) { IS_DRAGGING_LINEPOINT = true; LINEPOINT = ins; controller.executeCommand( new OldAddLinePoint(r, ins, me.getX(), me.getY())); return; } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/UniversalListener.java0000644000175000017500000001146412533641120026526 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.ComponentAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.Collections; import java.util.Vector; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.diagram.SelectorFrame; import com.baselet.diagram.SelectorOld; import com.baselet.element.interfaces.GridElement; import com.baselet.element.sticking.StickableMap; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.Command; import com.baselet.gui.command.Controller; import com.baselet.gui.command.Macro; import com.baselet.gui.command.Move; public abstract class UniversalListener extends ComponentAdapter implements MouseListener, MouseMotionListener { protected DiagramHandler handler; protected DrawPanel diagram; public SelectorOld selector; protected Controller controller; private int _xOffset, _yOffset; private boolean disableElementMovement = true; // is true after mouseReleased until the next mousePressed AND if the lasso is active private int old_x_eff, old_y_eff; private int new_x_eff, new_y_eff; protected UniversalListener(DiagramHandler handler) { this.handler = handler; diagram = handler.getDrawPanel(); selector = diagram.getSelector(); controller = handler.getController(); } @Override public void mouseClicked(MouseEvent arg0) {} @Override public void mouseEntered(MouseEvent me) {} @Override public void mousePressed(MouseEvent me) { disableElementMovement = false; CurrentGui.getInstance().getGui().requestFocus(); // to avoid beeing stuck in the propertyPanel Point off = getOffset(me); _xOffset = off.x; _yOffset = off.y; // everytime a mouse is pressed within a listener the gui gets the current diagram! CurrentDiagram.getInstance().setCurrentDiagramHandler(handler); if (CurrentDiagram.getInstance().getDiagramHandler() != null) { int factor = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); CurrentGui.getInstance().getGui().setValueOfZoomDisplay(factor); } } @Override public void mouseReleased(MouseEvent me) { disableElementMovement = true; if (selector.isSelectorFrameActive()) { SelectorFrame selframe = selector.getSelectorFrame(); diagram.remove(selframe); selector.deselectAll(); selector.multiSelect(Converter.convert(selframe.getBounds())); selector.setSelectorFrameActive(false); diagram.repaint(); } diagram.updatePanelAndScrollbars(); } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseMoved(MouseEvent me) { } @Override public void mouseDragged(MouseEvent me) { // Get new mouse coordinates if (selector.isSelectorFrameActive()) { selector.getSelectorFrame().resizeTo(getOffset(me).getX(), getOffset(me).getY()); disableElementMovement = true; return; } else if (disableElementMovement()) { return; } Point off = getOffset(me); int xNewOffset = off.x; int yNewOffset = off.y; int gridSize = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); new_x_eff = gridSize * ((xNewOffset - gridSize / 2) / gridSize); new_y_eff = gridSize * ((yNewOffset - gridSize / 2) / gridSize); old_x_eff = gridSize * ((_xOffset - gridSize / 2) / gridSize); old_y_eff = gridSize * ((_yOffset - gridSize / 2) / gridSize); _xOffset = xNewOffset; _yOffset = yNewOffset; } // only call after mouseDragged protected final boolean disableElementMovement() { return disableElementMovement; } // only call after mouseDragged protected final Point getOldCoordinate() { return new Point(old_x_eff, old_y_eff); } // only call after mouseDragged protected final Point getOldCoordinateNotRounded() { return new Point(_xOffset, _yOffset); } // only call after mouseDragged protected final Point getNewCoordinate() { return new Point(new_x_eff, new_y_eff); } protected abstract Point getOffset(MouseEvent me); protected void dragDiagram() { if (disableElementMovement()) { return; } Point newp = getNewCoordinate(); Point oldp = getOldCoordinate(); int diffx = newp.x - oldp.x; int diffy = newp.y - oldp.y; if (diffx != 0 || diffy != 0) { Vector moveCommands = new Vector(); for (GridElement e : diagram.getGridElements()) { moveCommands.add(new Move(Collections. emptySet(), e, diffx, diffy, oldp, false, false, true, StickableMap.EMPTY_MAP)); } controller.executeCommand(new Macro(moveCommands)); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/PaletteComboBoxListener.java0000644000175000017500000000254512533641120027605 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import javax.swing.JComboBox; import com.baselet.control.Main; import com.baselet.gui.CurrentGui; public class PaletteComboBoxListener implements ActionListener, MouseWheelListener { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JComboBox) { String paletteName = ((JComboBox) e.getSource()).getSelectedItem().toString(); CurrentGui.getInstance().getGui().showPalette(paletteName); setZoom(); } } @Override public void mouseWheelMoved(MouseWheelEvent e) { if (e.getSource() instanceof JComboBox) { JComboBox comboBox = (JComboBox) e.getSource(); int newIndex = comboBox.getSelectedIndex() + e.getWheelRotation(); // wheelrotation is -1 (up) or +1 (down) if (comboBox.getItemAt(newIndex) != null) { String newSelectedItem = comboBox.getItemAt(newIndex).toString(); CurrentGui.getInstance().getGui().showPalette(newSelectedItem); comboBox.setSelectedIndex(newIndex); setZoom(); } } } private void setZoom() { if (Main.getInstance().getPalette() != null) { int factor = Main.getInstance().getPalette().getGridSize(); CurrentGui.getInstance().getGui().setValueOfZoomDisplay(factor); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/PropertyPanelListener.java0000644000175000017500000000547012533641120027362 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import com.baselet.control.Main; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.CustomPreviewHandler; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.ChangePanelAttributes; import com.baselet.gui.command.CustomCodePropertyChanged; import com.baselet.gui.command.HelpPanelChanged; public class PropertyPanelListener implements KeyListener, DocumentListener { public PropertyPanelListener() {} @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == '\u001b') { // ESC Key: Leaves the Property Panel CurrentGui.getInstance().getGui().requestFocus(); } } @Override public void changedUpdate(DocumentEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { updateGridElement(); } }); } protected void updateGridElement() { GridElement gridElement = Main.getInstance().getEditedGridElement(); String s = CurrentGui.getInstance().getGui().getPropertyPane().getText(); DiagramHandler handler = CurrentDiagram.getInstance().getDiagramHandler(); if (gridElement != null) { // only create command if changes were made if (!s.equals(gridElement.getPanelAttributes())) { int newCaretPos = CurrentGui.getInstance().getGui().getPropertyPane().getTextComponent().getCaretPosition(); int oldCaretPos = newCaretPos - (s.length() - gridElement.getPanelAttributes().length()); if (Main.getHandlerForElement(gridElement) instanceof CustomPreviewHandler) { Main.getHandlerForElement(gridElement).getController().executeCommand(new CustomCodePropertyChanged(gridElement.getPanelAttributes(), s, oldCaretPos, newCaretPos)); } else { Main.getHandlerForElement(gridElement).getController().executeCommand(new ChangePanelAttributes(gridElement, gridElement.getPanelAttributes(), s, oldCaretPos, newCaretPos)); } } } else if (handler != null && !s.equals(handler.getHelpText())) { // help panel has been edited handler.getController().executeCommand(new HelpPanelChanged(s)); } // Scrollbars must be updated cause some entities can grow out of screen border by typing text inside (eg: autoresize custom elements) if (handler != null) { handler.getDrawPanel().updatePanelAndScrollbars(); } } @Override public void keyReleased(KeyEvent e) {} @Override public void keyPressed(KeyEvent e) {} @Override public void insertUpdate(DocumentEvent e) {} @Override public void removeUpdate(DocumentEvent e) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/DividerListener.java0000644000175000017500000000162112533641120026136 0ustar benbenpackage com.baselet.gui.listener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import com.baselet.control.Main; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.PaletteHandler; public class DividerListener implements ComponentListener { @Override public void componentHidden(ComponentEvent e) {} @Override public void componentMoved(ComponentEvent e) {} @Override public void componentResized(ComponentEvent e) { PaletteHandler p = Main.getInstance().getPalette(); if (p != null && p.getDrawPanel() != null) { p.getDrawPanel().updatePanelAndScrollbars(); } DiagramHandler h = CurrentDiagram.getInstance().getDiagramHandler(); if (h != null && h.getDrawPanel() != null) { h.getDrawPanel().updatePanelAndScrollbars(); } } @Override public void componentShown(ComponentEvent e) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/CustomPreviewEntityListener.java0000644000175000017500000000144112533641120030561 0ustar benbenpackage com.baselet.gui.listener; import java.util.HashMap; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; public class CustomPreviewEntityListener extends GridElementListener { private static HashMap entitylistener = new HashMap(); public static CustomPreviewEntityListener getInstance(DiagramHandler handler) { if (!entitylistener.containsKey(handler)) { entitylistener.put(handler, new CustomPreviewEntityListener(handler)); } return entitylistener.get(handler); } public CustomPreviewEntityListener(DiagramHandler handler) { super(handler); } @Override public void mouseDoubleClicked(GridElement me) { } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/HyperLinkActiveListener.java0000644000175000017500000000074112533641120027613 0ustar benbenpackage com.baselet.gui.listener; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import com.baselet.gui.BrowserLauncher; public class HyperLinkActiveListener implements HyperlinkListener { @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { try { BrowserLauncher.openURL(e.getURL().toString()); } catch (Throwable t) { t.printStackTrace(); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/listener/GridElementListener.java0000644000175000017500000003310212533641120026746 0ustar benbenpackage com.baselet.gui.listener; import java.awt.Component; import java.awt.event.MouseEvent; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.Vector; import javax.swing.JComponent; import javax.swing.JPopupMenu; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.Constants; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Direction; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.PaletteHandler; import com.baselet.diagram.SelectorFrame; import com.baselet.element.ElementFactorySwing; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.element.Relation; import com.baselet.element.sticking.StickableMap; import com.baselet.element.sticking.Stickables; import com.baselet.element.sticking.StickingPolygon; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.AddElement; import com.baselet.gui.command.Command; import com.baselet.gui.command.Macro; import com.baselet.gui.command.Move; import com.baselet.gui.command.MoveEnd; import com.baselet.gui.command.OldMoveLinePoint; import com.baselet.gui.command.OldRelationLinePoint; import com.baselet.gui.command.OldResize; public class GridElementListener extends UniversalListener { private static final Logger log = Logger.getLogger(GridElementListener.class); protected boolean IS_DRAGGING = false; protected boolean IS_DRAGGING_DIAGRAM = false; protected boolean IS_DRAGGED_FROM_PALETTE = false; private boolean FIRST_DRAG = true; private Vector FIRST_MOVE_COMMANDS = null; private Point POINT_BEFORE_MOVE = null; protected boolean DESELECT_MULTISEL = false; private boolean LASSO_ACTIVE = false; private Rectangle lassoToleranceRectangle; private final int lassoTolerance = 2; private Point mousePressedPoint; private Set resizeDirection; public GridElementListener(DiagramHandler handler) { super(handler); } @Override public void mouseDragged(MouseEvent me) { super.mouseDragged(me); log.debug("Entity dragged"); GridElement e = getGridElement(me); // Lasso selection is only activated if mouse is moved more than lasso_tolerance to avoid accidential activation instead of selecting the entity if (LASSO_ACTIVE && lassoToleranceRectangle != null && !lassoToleranceRectangle.contains(getOffset(me))) { dragLasso(me, e); return; } if (disableElementMovement()) { return; } if (IS_DRAGGING_DIAGRAM) { dragDiagram(); } if (IS_DRAGGING) { dragEntity(me.isShiftDown(), e); } } private GridElement getGridElement(MouseEvent me) { return handler.getDrawPanel().getElementToComponent(me.getComponent()); } @Override protected Point getOffset(MouseEvent me) { return new Point(me.getX() + me.getComponent().getX(), me.getY() + me.getComponent().getY()); } @Override public void mouseMoved(MouseEvent me) { super.mouseMoved(me); GridElement e = getGridElement(me); if (IS_DRAGGED_FROM_PALETTE) { log.debug("mouseMoved with dragged"); e.setLocation(me.getX() - 100, me.getY() - 20); } resizeDirection = e.getResizeArea(me.getX(), me.getY()); Point point = new Point(me.getX() + e.getRectangle().getX(), me.getY() + e.getRectangle().getY()); if (!e.isSelectableOn(point)) { CurrentGui.getInstance().getGui().setCursor(Constants.DEFAULT_CURSOR); } else if (resizeDirection.isEmpty()) { CurrentGui.getInstance().getGui().setCursor(Constants.HAND_CURSOR); } else if (resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.RIGHT) || resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.LEFT)) { CurrentGui.getInstance().getGui().setCursor(Constants.NE_CURSOR); } else if (resizeDirection.contains(Direction.DOWN) && resizeDirection.contains(Direction.RIGHT) || resizeDirection.contains(Direction.UP) && resizeDirection.contains(Direction.LEFT)) { CurrentGui.getInstance().getGui().setCursor(Constants.NW_CURSOR); } else if (resizeDirection.contains(Direction.UP) || resizeDirection.contains(Direction.DOWN)) { CurrentGui.getInstance().getGui().setCursor(Constants.TB_CURSOR); } else if (resizeDirection.contains(Direction.LEFT) || resizeDirection.contains(Direction.RIGHT)) { CurrentGui.getInstance().getGui().setCursor(Constants.LR_CURSOR); } } private void showContextMenu(GridElement ge, int x, int y) { if (!selector.getSelectedElements().contains(ge)) { selector.selectOnly(ge); } selector.setDominantEntity(ge); JPopupMenu contextMenu = CurrentGui.getInstance().getGui().getContextMenu(ge); if (contextMenu != null) { contextMenu.show((Component) ge.getComponent(), x, y); } } @Override public void mousePressed(MouseEvent me) { super.mousePressed(me); GridElement e = getGridElement(me); mousePressedPoint = getOffset(me); // deselect elements of all other drawpanels for (DiagramHandler h : Main.getInstance().getDiagramsAndPalettes()) { if (!h.equals(handler)) { h.getDrawPanel().getSelector().deselectAllWithoutUpdatePropertyPanel(); } } if (me.getButton() == MouseEvent.BUTTON3) { showContextMenu(e, me.getX(), me.getY()); } else if (me.getButton() == MouseEvent.BUTTON2) { IS_DRAGGING_DIAGRAM = true; } else if (me.getButton() == MouseEvent.BUTTON1) { if (me.getClickCount() == 1) { pressedLeftButton(me); } if (me.getClickCount() == 2) { mouseDoubleClicked(e); } } } private void pressedLeftButton(MouseEvent me) { GridElement e = getGridElement(me); // Ctrl + Mouseclick initializes the lasso if ((me.getModifiers() & SystemInfo.META_KEY.getMask()) != 0) { initializeLasso(); } IS_DRAGGING = true; if ((me.getModifiers() & SystemInfo.META_KEY.getMask()) != 0) { if (selector.isSelected(e)) { DESELECT_MULTISEL = true; } else { selector.select(e); } } if (!selector.getSelectedElements().contains(e)) { selector.selectOnly(e); } else { selector.updateSelectorInformation(e); } } public void mouseDoubleClicked(GridElement me) { GridElement e = ElementFactorySwing.createCopy(me); e.setProperty(GroupFacet.KEY, null); GridElementListener eListener = handler.getEntityListener(e); Command cmd; int gridSize = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); cmd = new AddElement(e, me.getRectangle().x + gridSize * 2, me.getRectangle().y + gridSize * 2); controller.executeCommand(cmd); selector.selectOnly(e); eListener.FIRST_DRAG = true; } @Override public void mouseReleased(MouseEvent me) { super.mouseReleased(me); // log.debug("Entity mouse released"); if (IS_DRAGGED_FROM_PALETTE) { IS_DRAGGED_FROM_PALETTE = false; } GridElement e = getGridElement(me); if ((me.getModifiers() & SystemInfo.META_KEY.getMask()) != 0) { if (selector.isSelected(e) && DESELECT_MULTISEL) { selector.deselect(e); } } if (IS_DRAGGING && !FIRST_DRAG) { // if mouse is dragged and element really has been dragged around execute moveend controller.executeCommand(new MoveEnd(e)); } DESELECT_MULTISEL = false; IS_DRAGGING = false; IS_DRAGGING_DIAGRAM = false; FIRST_DRAG = true; FIRST_MOVE_COMMANDS = null; POINT_BEFORE_MOVE = null; if (LASSO_ACTIVE) { LASSO_ACTIVE = false; ((JComponent) me.getComponent()).remove(selector.getSelectorFrame()); } } private void initializeLasso() { lassoToleranceRectangle = new Rectangle(mousePressedPoint.x - lassoTolerance, mousePressedPoint.y - lassoTolerance, lassoTolerance * 2, lassoTolerance * 2); LASSO_ACTIVE = true; SelectorFrame selframe = selector.getSelectorFrame(); selframe.setLocation(Converter.convert(mousePressedPoint)); selframe.setSize(1, 1); CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().add(selframe, 0); CurrentGui.getInstance().getGui().setCursor(Constants.DEFAULT_CURSOR); } private void dragLasso(MouseEvent me, GridElement e) { selector.setSelectorFrameActive(true); selector.getSelectorFrame().setDisplacement(e.getRectangle().x, e.getRectangle().y); selector.getSelectorFrame().resizeTo(me.getX(), me.getY()); // Subtract difference between entityx/entityy and the position of the mouse cursor selector.deselectAll(); // If lasso is active the clicked and therefore automatically selected entity gets unselected } /** * Dragging entities must be a Macro, because undo should undo the full move (and not only a small part which would * happen with many short Move actions) and it must consider sticking relations at the dragging-start and later * @param mainElement * @param directions * @param b */ private void dragEntity(boolean isShiftKeyDown, GridElement mainElement) { DESELECT_MULTISEL = false; Point newp = getNewCoordinate(); Point oldp = getOldCoordinate(); int diffx = newp.x - oldp.x; int diffy = newp.y - oldp.y; List elementsToMove = selector.getSelectedElements(); if (!resizeDirection.isEmpty()) { elementsToMove = Arrays.asList(mainElement); } if (FIRST_MOVE_COMMANDS == null) { POINT_BEFORE_MOVE = getOldCoordinateNotRounded(); // must use exact coordinates eg for Relation which calculates distances from lines (to possibly drag new points out of it) FIRST_MOVE_COMMANDS = calculateFirstMoveCommands(diffx, diffy, oldp, elementsToMove, isShiftKeyDown, false, handler, resizeDirection); } else if (diffx != 0 || diffy != 0) { Vector commands = continueDragging(diffx, diffy, POINT_BEFORE_MOVE, elementsToMove); POINT_BEFORE_MOVE = new Point(POINT_BEFORE_MOVE.getX() + diffx, POINT_BEFORE_MOVE.getY() + diffy); controller.executeCommand(new Macro(commands)); FIRST_DRAG = false; } } static Vector calculateFirstMoveCommands(int diffx, int diffy, Point oldp, Collection entitiesToBeMoved, boolean isShiftKeyDown, boolean useSetLocation, DiagramHandler handler, Set directions) { Vector moveCommands = new Vector(); Vector linepointCommands = new Vector(); List stickables = handler.getDrawPanel().getStickables(entitiesToBeMoved); for (GridElement ge : entitiesToBeMoved) { // reduce stickables to those which really stick at the element at move-start StickableMap stickingStickables = Stickables.getStickingPointsWhichAreConnectedToStickingPolygon(ge.generateStickingBorder(), stickables); moveCommands.add(new Move(directions, ge, diffx, diffy, oldp, isShiftKeyDown, true, useSetLocation, stickingStickables)); handleStickingOfOldRelation(diffx, diffy, entitiesToBeMoved, handler, directions, linepointCommands, ge); } Vector allCommands = new Vector(); allCommands.addAll(moveCommands); allCommands.addAll(linepointCommands); return allCommands; } // for elements which are not OldRelation themselves and if sticking is not disabled, handle the sticking-movement of old relations. SHOULD BE REMOVED AS SOON AS THE OLDRELATION CLASS IS REMOVED! @Deprecated private static void handleStickingOfOldRelation(int diffx, int diffy, Collection entitiesToBeMoved, DiagramHandler handler, Set directions, Vector linepointCommands, GridElement ge) { boolean stickingDisabled = !SharedConfig.getInstance().isStickingEnabled() || handler instanceof PaletteHandler; if (!(ge instanceof Relation || stickingDisabled)) { StickingPolygon stick = ge.generateStickingBorder(); if (stick != null && directions.isEmpty()) { // sticking on resizing is disabled for old relations Vector affectedRelationPoints = OldResize.getStickingRelationLinePoints(handler, stick); for (int j = 0; j < affectedRelationPoints.size(); j++) { OldRelationLinePoint tmpRlp = affectedRelationPoints.elementAt(j); if (entitiesToBeMoved.contains(tmpRlp.getRelation())) { continue; } linepointCommands.add(new OldMoveLinePoint(tmpRlp.getRelation(), tmpRlp.getLinePointId(), diffx, diffy)); } } } } /** * After the firstDragging is over, the vector of entities which should be dragged doesn't change (nothing starts sticking during dragging) * @param oldp * @param elementsToMove * @param directions * @return */ private Vector continueDragging(int diffx, int diffy, Point oldp, List elementsToMove) { boolean useSetLocation = elementsToMove.size() != 1; // if >1 elements are selected they will be moved Vector tmpVector = new Vector(); for (Command command : FIRST_MOVE_COMMANDS) { // use first move commands to identify the necessary commands and moved entities if (command instanceof Move) { Move m = (Move) command; tmpVector.add(new Move(resizeDirection, m.getEntity(), diffx, diffy, oldp, m.isShiftKeyDown(), FIRST_DRAG, useSetLocation, m.getStickables())); } else if (command instanceof OldMoveLinePoint) { OldMoveLinePoint m = (OldMoveLinePoint) command; tmpVector.add(new OldMoveLinePoint(m.getRelation(), m.getLinePointId(), diffx, diffy)); } } return tmpVector; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/0000755000175000017500000000000012533641120022502 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/MenuBuilder.java0000644000175000017500000001545212533641120025567 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.event.KeyEvent; import java.util.Collection; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JToggleButton; import com.baselet.control.constants.MenuConstants; import com.baselet.diagram.CustomPreviewHandler; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.PaletteHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.menu.MenuFactorySwing; public class MenuBuilder { private MenuFactorySwing menuFactory; private JMenu editMenu; private JMenuItem editUndo; private JMenuItem editRedo; private JMenuItem editDelete; private JMenuItem editSelectAll; private JMenuItem editGroup; private JMenuItem editUngroup; private JMenuItem editCut; private JMenuItem editCopy; private JMenuItem editPaste; private JMenuItem customNew; private JMenu customNewFromTemplate; private JMenuItem customEdit; private JToggleButton mailButton; public JMenuBar createMenu(JPanel searchPanel, JPanel zoomPanel, JToggleButton mailButton) { /*********** CREATE MENU *****************/ JMenuBar menu = new JMenuBar(); menuFactory = MenuFactorySwing.getInstance(); JMenu fileMenu = new JMenu(MenuConstants.FILE); fileMenu.setMnemonic(KeyEvent.VK_F); fileMenu.add(menuFactory.createNew()); fileMenu.add(menuFactory.createOpen()); fileMenu.add(menuFactory.createRecentFiles()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createGenerate()); fileMenu.add(menuFactory.createGenerateOptions()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createSave()); fileMenu.add(menuFactory.createSaveAs()); fileMenu.add(menuFactory.createExportAs()); fileMenu.add(menuFactory.createMailTo()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createEditCurrentPalette()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createOptions()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createPrint()); fileMenu.addSeparator(); fileMenu.add(menuFactory.createExit()); menu.add(fileMenu); editMenu = new JMenu(MenuConstants.EDIT); editMenu.setMnemonic(KeyEvent.VK_E); editMenu.add(editUndo = menuFactory.createUndo()); editMenu.add(editRedo = menuFactory.createRedo()); editMenu.add(editDelete = menuFactory.createDelete()); editMenu.addSeparator(); editMenu.add(editSelectAll = menuFactory.createSelectAll()); editMenu.add(editGroup = menuFactory.createGroup()); editMenu.add(editUngroup = menuFactory.createUngroup()); editMenu.addSeparator(); editMenu.add(editCopy = menuFactory.createCopy()); editMenu.add(editCut = menuFactory.createCut()); editMenu.add(editPaste = menuFactory.createPaste()); menu.add(editMenu); editDelete.setEnabled(false); editGroup.setEnabled(false); editCut.setEnabled(false); editPaste.setEnabled(false); editUngroup.setEnabled(false); // Custom Element Menu JMenu menu_custom = new JMenu(MenuConstants.CUSTOM_ELEMENTS); menu_custom.setMnemonic(KeyEvent.VK_C); menu_custom.add(customNew = menuFactory.createNewCustomElement()); menu_custom.add(customNewFromTemplate = menuFactory.createNewCustomElementFromTemplate()); menu_custom.add(customEdit = menuFactory.createEditSelected()); menu_custom.addSeparator(); menu_custom.add(menuFactory.createCustomElementTutorial()); menu.add(menu_custom); customEdit.setEnabled(false); // Help Menu JMenu helpMenu = new JMenu(MenuConstants.HELP); helpMenu.setMnemonic(KeyEvent.VK_H); helpMenu.add(menuFactory.createOnlineHelp()); helpMenu.add(menuFactory.createOnlineSampleDiagrams()); helpMenu.add(menuFactory.createVideoTutorials()); helpMenu.addSeparator(); helpMenu.add(menuFactory.createProgramHomepage()); helpMenu.add(menuFactory.createRateProgram()); helpMenu.addSeparator(); helpMenu.add(menuFactory.createAboutProgram()); menu.add(helpMenu); menu.add(searchPanel); menu.add(zoomPanel); this.mailButton = mailButton; menu.add(mailButton); return menu; } public void elementsSelected(Collection selectedElements) { if (selectedElements.isEmpty()) { editDelete.setEnabled(false); editGroup.setEnabled(false); editCut.setEnabled(false); // menu_edit_copy must remain enabled even if no entity is selected to allow the export of the full diagram to the system clipboard. } else { editDelete.setEnabled(true); editCut.setEnabled(true); boolean allElementsInGroup = true; for (GridElement e : selectedElements) { if (e.getGroup() == null) { allElementsInGroup = false; } } editUngroup.setEnabled(allElementsInGroup); editGroup.setEnabled(!allElementsInGroup && selectedElements.size() > 1); } } public void enablePasteMenuEntry() { editPaste.setEnabled(true); } public void setNewCustomElementMenuItemsEnabled(boolean enable) { customNew.setEnabled(enable); customNewFromTemplate.setEnabled(enable); } public void setEditCustomElementMenuItemEnabled(boolean enabled) { if (customEdit != null) { customEdit.setEnabled(enabled); } } public void setCustomElementEditMenuEnabled(boolean enabled) { editGroup.setEnabled(enabled); editUngroup.setEnabled(enabled); editDelete.setEnabled(enabled); editCut.setEnabled(enabled); editPaste.setEnabled(enabled); editCopy.setEnabled(enabled); editSelectAll.setEnabled(enabled); } public void updateGrayedOutMenuItems(DiagramHandler handler) { // These menuitems only get changed if this is not the palette or custompreview if (!(handler instanceof PaletteHandler) && !(handler instanceof CustomPreviewHandler)) { menuFactory.updateDiagramDependendComponents(); if (handler == null || handler.getDrawPanel().getGridElements().isEmpty()) { mailButton.setEnabled(false); } else { mailButton.setEnabled(true); } } // The menu_edit menuitems always work with the actual selected diagram (diagram, palette or custompreview), therefore we change it everytime if (handler == null || handler.getDrawPanel().getGridElements().isEmpty()) { editCopy.setEnabled(false); editSelectAll.setEnabled(false); } else if (handler instanceof CustomPreviewHandler) { setCustomElementEditMenuEnabled(false); } else { editMenu.setEnabled(true); // must be set to enabled explicitely because it could be deactivated from CustomPreview setCustomElementEditMenuEnabled(true); } if (handler == null || !handler.getController().isUndoable()) { editUndo.setEnabled(false); } else { editUndo.setEnabled(true); } if (handler == null || !handler.getController().isRedoable()) { editRedo.setEnabled(false); } else { editRedo.setEnabled(true); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/TabComponent.java0000644000175000017500000000747512533641120025753 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import com.baselet.control.Main; import com.baselet.diagram.DiagramHandler; @SuppressWarnings("serial") public class TabComponent extends JPanel { private DiagramHandler handler; private TabListener listener; private Color background; private JButton button; public TabComponent(final JTabbedPane pane, DiagramHandler handler) { super(new FlowLayout(FlowLayout.LEFT, 0, 0)); this.handler = handler; setOpaque(false); // make JLabel read titles from JTabbedPane JLabel label = new JLabel() { @Override public String getText() { int i = pane.indexOfTabComponent(TabComponent.this); if (i != -1) { return pane.getTitleAt(i); } return null; } }; label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 7)); add(label); button = new TabButton(); add(button); listener = new TabListener(handler, pane); addMouseListener(listener); background = getBackground(); } @Override public void setEnabled(boolean en) { super.setEnabled(en); if (en) { setBackground(background); addMouseListener(listener); } else { setBackground(Color.lightGray); removeMouseListener(listener); } button.setEnabled(en); } private class TabButton extends JButton implements MouseListener { public TabButton() { int size = 17; setPreferredSize(new Dimension(size, size)); setToolTipText("close this tab"); // Make it transparent setContentAreaFilled(false); // No need to be focusable setFocusable(false); setBorder(BorderFactory.createEtchedBorder()); setBorderPainted(false); // Making nice rollover effect // we use the same listener for all buttons addMouseListener(this); } @Override public void setEnabled(boolean en) { super.setEnabled(en); if (en) { addMouseListener(this); setToolTipText("close this tab"); } else { removeMouseListener(this); setToolTipText(null); } } @Override public void mouseEntered(MouseEvent e) { Component component = e.getComponent(); if (component instanceof AbstractButton) { AbstractButton button = (AbstractButton) component; button.setBorderPainted(true); } } @Override public void mouseExited(MouseEvent e) { Component component = e.getComponent(); if (component instanceof AbstractButton) { AbstractButton button = (AbstractButton) component; button.setBorderPainted(false); } } @Override public void mouseClicked(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { handler.doClose(); if (Main.getInstance().getDiagrams().size() == 0) { Main.getInstance().doNew(); } } @Override public void mouseReleased(MouseEvent arg0) { } // we don't want to update UI for this button @Override public void updateUI() {} // paint the cross @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); // shift the image for pressed buttons if (getModel().isPressed()) { g2.translate(1, 1); } g2.setColor(Color.BLACK); int delta = 6; g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1); g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1); g2.dispose(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/ZoomListener.java0000644000175000017500000000245412533641120026004 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.AWTEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import javax.swing.JComboBox; import com.baselet.diagram.CurrentDiagram; import com.baselet.gui.CurrentGui; public class ZoomListener implements ActionListener, MouseWheelListener { @Override public void actionPerformed(ActionEvent e) { handleEvent(e); } @Override public void mouseWheelMoved(MouseWheelEvent e) { handleEvent(e); } private void handleEvent(AWTEvent e) { if (CurrentGui.getInstance().getGui() instanceof StandaloneGUI && CurrentDiagram.getInstance().getDiagramHandler() != null) { // The offset is -1 (wheel up) or +1 (wheel down) or 0 (no wheel used) int offset = 0; if (e instanceof MouseWheelEvent) { offset = ((MouseWheelEvent) e).getWheelRotation(); } String zoomFactor = ((JComboBox) e.getSource()).getSelectedItem().toString(); zoomFactor = zoomFactor.substring(0, zoomFactor.length() - 2); // Cut the zoomvalue eg: "120%" to "12" int newZoomFactor = Integer.parseInt(zoomFactor) + offset; if (newZoomFactor > 0 && newZoomFactor < 21) { CurrentDiagram.getInstance().getDiagramHandler().setGridAndZoom(newZoomFactor); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/FileDrop.java0000644000175000017500000007441712533641120025066 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.io.Reader; import com.baselet.gui.standalone.FileDrop.TransferableObject; /** * This class makes it easy to drag and drop files from the operating * system to a Java program. Any java.awt.Component can be * dropped onto, but only javax.swing.JComponents will indicate * the drop event with a changed border. *

* To use this class, construct a new FileDrop by passing it the target component and a Listener to receive notification when file(s) have been dropped. Here is an example: *

*

 *      JPanel myPanel = new JPanel();
 *      new FileDrop( myPanel, new FileDrop.Listener()
 *      {   public void filesDropped( java.io.File[] files )
 *          {
 *              // handle file drop
 *              ...
 *          }   // end filesDropped
 *      }); // end FileDrop.Listener
 * 
*

* You can specify the border that will appear when files are being dragged by calling the constructor with a javax.swing.border.Border. Only JComponents will show any indication with a border. *

* You can turn on some debugging features by passing a PrintStream object (such as System.out) into the full constructor. A null value will result in no extra debugging information being output. *

*

* I'm releasing this code into the Public Domain. Enjoy. *

*

* Original author: Robert Harder, rharder@usa.net *

*

* 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. *

* * @author Robert Harder * @author rharder@users.sf.net * @version 1.0.1 */ @SuppressWarnings("all") public class FileDrop { private javax.swing.border.Border normalBorder; private java.awt.dnd.DropTargetListener dropListener; /** Discover if the running JVM is modern enough to have drag and drop. */ private static Boolean supportsDnD; // Default border color private static java.awt.Color defaultBorderColor = new java.awt.Color(0f, 0f, 1f, 0.25f); /** * Constructs a {@link FileDrop} with a default light-blue border * and, if c is a {@link java.awt.Container}, recursively * sets all elements contained within as drop targets, though only * the top level container will change borders. * * @param c * Component on which files will be dropped. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.awt.Component c, final Listener listener) { this(null, // Logging stream c, // Drop target javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border true, // Recursive listener); } // end constructor /** * Constructor with a default border and the option to recursively set drop targets. * If your component is a java.awt.Container, then each of its children * components will also listen for drops, though only the parent will change borders. * * @param c * Component on which files will be dropped. * @param recursive * Recursively set children as drop targets. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.awt.Component c, final boolean recursive, final Listener listener) { this(null, // Logging stream c, // Drop target javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border recursive, // Recursive listener); } // end constructor /** * Constructor with a default border and debugging optionally turned on. * With Debugging turned on, more status messages will be displayed to out. A common way to use this constructor is with System.out or System.err. A null value for * the parameter out will result in no debugging output. * * @param out * PrintStream to record debugging info or null for no debugging. * @param out * @param c * Component on which files will be dropped. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.io.PrintStream out, final java.awt.Component c, final Listener listener) { this(out, // Logging stream c, // Drop target javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), false, // Recursive listener); } // end constructor /** * Constructor with a default border, debugging optionally turned on * and the option to recursively set drop targets. * If your component is a java.awt.Container, then each of its children * components will also listen for drops, though only the parent will change borders. * With Debugging turned on, more status messages will be displayed to out. A common way to use this constructor is with System.out or System.err. A null value for * the parameter out will result in no debugging output. * * @param out * PrintStream to record debugging info or null for no debugging. * @param out * @param c * Component on which files will be dropped. * @param recursive * Recursively set children as drop targets. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.io.PrintStream out, final java.awt.Component c, final boolean recursive, final Listener listener) { this(out, // Logging stream c, // Drop target javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border recursive, // Recursive listener); } // end constructor /** * Constructor with a specified border * * @param c * Component on which files will be dropped. * @param dragBorder * Border to use on JComponent when dragging occurs. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.awt.Component c, final javax.swing.border.Border dragBorder, final Listener listener) { this( null, // Logging stream c, // Drop target dragBorder, // Drag border false, // Recursive listener); } // end constructor /** * Constructor with a specified border and the option to recursively set drop targets. * If your component is a java.awt.Container, then each of its children * components will also listen for drops, though only the parent will change borders. * * @param c * Component on which files will be dropped. * @param dragBorder * Border to use on JComponent when dragging occurs. * @param recursive * Recursively set children as drop targets. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.awt.Component c, final javax.swing.border.Border dragBorder, final boolean recursive, final Listener listener) { this( null, c, dragBorder, recursive, listener); } // end constructor /** * Constructor with a specified border and debugging optionally turned on. * With Debugging turned on, more status messages will be displayed to out. A common way to use this constructor is with System.out or System.err. A null value for * the parameter out will result in no debugging output. * * @param out * PrintStream to record debugging info or null for no debugging. * @param c * Component on which files will be dropped. * @param dragBorder * Border to use on JComponent when dragging occurs. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.io.PrintStream out, final java.awt.Component c, final javax.swing.border.Border dragBorder, final Listener listener) { this( out, // Logging stream c, // Drop target dragBorder, // Drag border false, // Recursive listener); } // end constructor /** * Full constructor with a specified border and debugging optionally turned on. * With Debugging turned on, more status messages will be displayed to out. A common way to use this constructor is with System.out or System.err. A null value for * the parameter out will result in no debugging output. * * @param out * PrintStream to record debugging info or null for no debugging. * @param c * Component on which files will be dropped. * @param dragBorder * Border to use on JComponent when dragging occurs. * @param recursive * Recursively set children as drop targets. * @param listener * Listens for filesDropped. * @since 1.0 */ public FileDrop( final java.io.PrintStream out, final java.awt.Component c, final javax.swing.border.Border dragBorder, final boolean recursive, final Listener listener) { if (supportsDnD()) { // Make a drop listener dropListener = new java.awt.dnd.DropTargetListener() { @Override public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) { log(out, "FileDrop: dragEnter event."); // Is this an acceptable drag event? if (isDragOk(out, evt)) { // If it's a Swing component, set its border if (c instanceof javax.swing.JComponent) { javax.swing.JComponent jc = (javax.swing.JComponent) c; normalBorder = jc.getBorder(); log(out, "FileDrop: normal border saved."); jc.setBorder(dragBorder); log(out, "FileDrop: drag border set."); } // end if: JComponent // Acknowledge that it's okay to enter // evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE ); evt.acceptDrag(java.awt.dnd.DnDConstants.ACTION_COPY); log(out, "FileDrop: event accepted."); } // end if: drag ok else { // Reject the drag event evt.rejectDrag(); log(out, "FileDrop: event rejected."); } // end else: drag not ok } // end dragEnter @Override public void dragOver(java.awt.dnd.DropTargetDragEvent evt) { // This is called continually as long as the mouse is // over the drag target. } // end dragOver @Override public void drop(java.awt.dnd.DropTargetDropEvent evt) { log(out, "FileDrop: drop event."); try { // Get whatever was dropped java.awt.datatransfer.Transferable tr = evt.getTransferable(); // Is it a file list? if (tr.isDataFlavorSupported(java.awt.datatransfer.DataFlavor.javaFileListFlavor)) { // Say we'll take it. // evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE ); evt.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY); log(out, "FileDrop: file list accepted."); // Get a useful list java.util.List fileList = (java.util.List) tr.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor); // Convert list to array java.io.File[] filesTemp = new java.io.File[fileList.size()]; fileList.toArray(filesTemp); final java.io.File[] files = filesTemp; // Alert listener to drop. if (listener != null) { listener.filesDropped(files); } // Mark that drop is completed. evt.getDropTargetContext().dropComplete(true); log(out, "FileDrop: drop complete."); } // end if: file list else // this section will check for a reader flavor. { // Thanks, Nathan! // BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. DataFlavor[] flavors = tr.getTransferDataFlavors(); boolean handled = false; for (DataFlavor flavor : flavors) { if (flavor.isRepresentationClassReader()) { // Say we'll take it. // evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE ); evt.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY); log(out, "FileDrop: reader accepted."); Reader reader = flavor.getReaderForText(tr); BufferedReader br = new BufferedReader(reader); if (listener != null) { listener.filesDropped(createFileArray(br, out)); } // Mark that drop is completed. evt.getDropTargetContext().dropComplete(true); log(out, "FileDrop: drop complete."); handled = true; break; } } if (!handled) { log(out, "FileDrop: not a file list or reader - abort."); evt.rejectDrop(); } // END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. } // end else: not a file list } // end try catch (java.io.IOException io) { log(out, "FileDrop: IOException - abort:"); io.printStackTrace(out); evt.rejectDrop(); } // end catch IOException catch (java.awt.datatransfer.UnsupportedFlavorException ufe) { log(out, "FileDrop: UnsupportedFlavorException - abort:"); ufe.printStackTrace(out); evt.rejectDrop(); } // end catch: UnsupportedFlavorException finally { // If it's a Swing component, reset its border if (c instanceof javax.swing.JComponent) { javax.swing.JComponent jc = (javax.swing.JComponent) c; jc.setBorder(normalBorder); log(out, "FileDrop: normal border restored."); } // end if: JComponent } // end finally } // end drop @Override public void dragExit(java.awt.dnd.DropTargetEvent evt) { log(out, "FileDrop: dragExit event."); // If it's a Swing component, reset its border if (c instanceof javax.swing.JComponent) { javax.swing.JComponent jc = (javax.swing.JComponent) c; jc.setBorder(normalBorder); log(out, "FileDrop: normal border restored."); } // end if: JComponent } // end dragExit @Override public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) { log(out, "FileDrop: dropActionChanged event."); // Is this an acceptable drag event? if (isDragOk(out, evt)) { // evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE ); evt.acceptDrag(java.awt.dnd.DnDConstants.ACTION_COPY); log(out, "FileDrop: event accepted."); } // end if: drag ok else { evt.rejectDrag(); log(out, "FileDrop: event rejected."); } // end else: drag not ok } // end dropActionChanged }; // end DropTargetListener // Make the component (and possibly children) drop targets makeDropTarget(out, c, recursive); } // end if: supports dnd else { log(out, "FileDrop: Drag and drop is not supported with this JVM"); } // end else: does not support DnD } // end constructor private static boolean supportsDnD() { // Static Boolean if (supportsDnD == null) { boolean support = false; try { Class.forName("java.awt.dnd.DnDConstants"); support = true; } // end try catch (Exception e) { support = false; } // end catch supportsDnD = Boolean.valueOf(support); } // end if: first time through return supportsDnD.booleanValue(); } // end supportsDnD // BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. private static String ZERO_CHAR_STRING = "" + (char) 0; private static File[] createFileArray(BufferedReader bReader, PrintStream out) { try { java.util.List list = new java.util.ArrayList(); java.lang.String line = null; while ((line = bReader.readLine()) != null) { try { // kde seems to append a 0 char to the end of the reader if (ZERO_CHAR_STRING.equals(line)) { continue; } java.io.File file = new java.io.File(new java.net.URI(line)); list.add(file); } catch (Exception ex) { log(out, "Error with " + line + ": " + ex.getMessage()); } } return (java.io.File[]) list.toArray(new File[list.size()]); } catch (IOException ex) { log(out, "FileDrop: IOException"); } return new File[0]; } // END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. private void makeDropTarget(final java.io.PrintStream out, final java.awt.Component c, boolean recursive) { // Make drop target final java.awt.dnd.DropTarget dt = new java.awt.dnd.DropTarget(); try { dt.addDropTargetListener(dropListener); } // end try catch (java.util.TooManyListenersException e) { e.printStackTrace(); log(out, "FileDrop: Drop will not work due to previous error. Do you have another listener attached?"); } // end catch // Listen for hierarchy changes and remove the drop target when the parent gets cleared out. c.addHierarchyListener(new java.awt.event.HierarchyListener() { @Override public void hierarchyChanged(java.awt.event.HierarchyEvent evt) { log(out, "FileDrop: Hierarchy changed."); java.awt.Component parent = c.getParent(); if (parent == null) { c.setDropTarget(null); log(out, "FileDrop: Drop target cleared from component."); } // end if: null parent else { new java.awt.dnd.DropTarget(c, dropListener); log(out, "FileDrop: Drop target added to component."); } // end else: parent not null } // end hierarchyChanged }); // end hierarchy listener if (c.getParent() != null) { new java.awt.dnd.DropTarget(c, dropListener); } if (recursive && c instanceof java.awt.Container) { // Get the container java.awt.Container cont = (java.awt.Container) c; // Get it's components java.awt.Component[] comps = cont.getComponents(); // Set it's components as listeners also for (Component comp : comps) { makeDropTarget(out, comp, recursive); } } // end if: recursively set components as listener } // end dropListener /** Determine if the dragged data is a file list. */ private boolean isDragOk(final java.io.PrintStream out, final java.awt.dnd.DropTargetDragEvent evt) { boolean ok = false; // Get data flavors being dragged java.awt.datatransfer.DataFlavor[] flavors = evt.getCurrentDataFlavors(); // See if any of the flavors are a file list int i = 0; while (!ok && i < flavors.length) { // BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. // Is the flavor a file list? final DataFlavor curFlavor = flavors[i]; if (curFlavor.equals(java.awt.datatransfer.DataFlavor.javaFileListFlavor) || curFlavor.isRepresentationClassReader()) { ok = true; } // END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added. i++; } // end while: through flavors // If logging is enabled, show data flavors if (out != null) { if (flavors.length == 0) { log(out, "FileDrop: no data flavors."); } for (i = 0; i < flavors.length; i++) { log(out, flavors[i].toString()); } } // end if: logging enabled return ok; } // end isDragOk /** Outputs message to out if it's not null. */ private static void log(java.io.PrintStream out, String message) { // Log message if requested if (out != null) { out.println(message); } } // end log /** * Removes the drag-and-drop hooks from the component and optionally * from the all children. You should call this if you add and remove * components after you've set up the drag-and-drop. * This will recursively unregister all components contained within * c if c is a {@link java.awt.Container}. * * @param c * The component to unregister as a drop target * @since 1.0 */ public static boolean remove(java.awt.Component c) { return remove(null, c, true); } // end remove /** * Removes the drag-and-drop hooks from the component and optionally * from the all children. You should call this if you add and remove * components after you've set up the drag-and-drop. * * @param out * Optional {@link java.io.PrintStream} for logging drag and drop messages * @param c * The component to unregister * @param recursive * Recursively unregister components within a container * @since 1.0 */ public static boolean remove(java.io.PrintStream out, java.awt.Component c, boolean recursive) { // Make sure we support dnd. if (supportsDnD()) { log(out, "FileDrop: Removing drag-and-drop hooks."); c.setDropTarget(null); if (recursive && c instanceof java.awt.Container) { java.awt.Component[] comps = ((java.awt.Container) c).getComponents(); for (Component comp : comps) { remove(out, comp, recursive); } return true; } // end if: recursive else { return false; } } // end if: supports DnD else { return false; } } // end remove /* ******** I N N E R I N T E R F A C E L I S T E N E R ******** */ /** * Implement this inner interface to listen for when files are dropped. For example * your class declaration may begin like this:
	 *      public class MyClass implements FileDrop.Listener
	 *      ...
	 *      public void filesDropped( java.io.File[] files )
	 *      {
	 *          ...
	 *      }   // end filesDropped
	 *      ...
	 * 
* * @since 1.1 */ public static interface Listener { /** * This method is called when files have been successfully dropped. * * @param files * An array of Files that were dropped. * @since 1.0 */ public abstract void filesDropped(java.io.File[] files); } // end inner-interface Listener /** * At last an easy way to encapsulate your custom objects for dragging and dropping * in your Java programs! * When you need to create a {@link java.awt.datatransfer.Transferable} object, * use this class to wrap your object. * For example: * *
	 * 
	 *      ...
	 *      MyCoolClass myObj = new MyCoolClass();
	 *      Transferable xfer = new TransferableObject( myObj );
	 *      ...
	 * 
	 * 
* * Or if you need to know when the data was actually dropped, like when you're * moving data out of a list, say, you can use the {@link TransferableObject.Fetcher} inner class to return your object Just in Time. * For example: * *
	 * 
	 *      ...
	 *      final MyCoolClass myObj = new MyCoolClass();
	 *
	 *      TransferableObject.Fetcher fetcher = new TransferableObject.Fetcher()
	 *      {   public Object getObject(){ return myObj; }
	 *      }; // end fetcher
	 *
	 *      Transferable xfer = new TransferableObject( fetcher );
	 *      ...
	 * 
	 * 
* * The {@link java.awt.datatransfer.DataFlavor} associated with {@link TransferableObject} has the representation class net.iharder.dnd.TransferableObject.class and MIME type application/x-net.iharder.dnd.TransferableObject. * This data flavor is accessible via the static {@link #DATA_FLAVOR} property. *

* I'm releasing this code into the Public Domain. Enjoy. *

* * @author Robert Harder * @author rob@iharder.net * @version 1.2 */ public static class TransferableObject implements java.awt.datatransfer.Transferable { /** * The MIME type for {@link #DATA_FLAVOR} is application/x-net.iharder.dnd.TransferableObject. * * @since 1.1 */ public static final String MIME_TYPE = "application/x-net.iharder.dnd.TransferableObject"; /** * The default {@link java.awt.datatransfer.DataFlavor} for {@link TransferableObject} has the representation class net.iharder.dnd.TransferableObject.class and the MIME type application/x-net.iharder.dnd.TransferableObject. * * @since 1.1 */ public static final java.awt.datatransfer.DataFlavor DATA_FLAVOR = new java.awt.datatransfer.DataFlavor(FileDrop.TransferableObject.class, MIME_TYPE); private Fetcher fetcher; private Object data; private java.awt.datatransfer.DataFlavor customFlavor; /** * Creates a new {@link TransferableObject} that wraps data. * Along with the {@link #DATA_FLAVOR} associated with this class, * this creates a custom data flavor with a representation class * determined from data.getClass() and the MIME type application/x-net.iharder.dnd.TransferableObject. * * @param data * The data to transfer * @since 1.1 */ public TransferableObject(Object data) { this.data = data; customFlavor = new java.awt.datatransfer.DataFlavor(data.getClass(), MIME_TYPE); } // end constructor /** * Creates a new {@link TransferableObject} that will return the * object that is returned by fetcher. * No custom data flavor is set other than the default {@link #DATA_FLAVOR}. * * @see Fetcher * @param fetcher * The {@link Fetcher} that will return the data object * @since 1.1 */ public TransferableObject(Fetcher fetcher) { this.fetcher = fetcher; } // end constructor /** * Creates a new {@link TransferableObject} that will return the * object that is returned by fetcher. * Along with the {@link #DATA_FLAVOR} associated with this class, * this creates a custom data flavor with a representation class dataClass * and the MIME type application/x-net.iharder.dnd.TransferableObject. * * @see Fetcher * @param dataClass * The {@link java.lang.Class} to use in the custom data flavor * @param fetcher * The {@link Fetcher} that will return the data object * @since 1.1 */ public TransferableObject(Class dataClass, Fetcher fetcher) { this.fetcher = fetcher; customFlavor = new java.awt.datatransfer.DataFlavor(dataClass, MIME_TYPE); } // end constructor /** * Returns the custom {@link java.awt.datatransfer.DataFlavor} associated * with the encapsulated object or null if the {@link Fetcher} constructor was used without passing a {@link java.lang.Class}. * * @return The custom data flavor for the encapsulated object * @since 1.1 */ public java.awt.datatransfer.DataFlavor getCustomDataFlavor() { return customFlavor; } // end getCustomDataFlavor /* ******** T R A N S F E R A B L E M E T H O D S ******** */ /** * Returns a two- or three-element array containing first * the custom data flavor, if one was created in the constructors, * second the default {@link #DATA_FLAVOR} associated with {@link TransferableObject}, and third the {@link java.awt.datatransfer.DataFlavor.stringFlavor}. * * @return An array of supported data flavors * @since 1.1 */ @Override public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() { if (customFlavor != null) { return new java.awt.datatransfer.DataFlavor[] { customFlavor, DATA_FLAVOR, java.awt.datatransfer.DataFlavor.stringFlavor }; // end flavors array } else { return new java.awt.datatransfer.DataFlavor[] { DATA_FLAVOR, java.awt.datatransfer.DataFlavor.stringFlavor }; // end flavors array } } // end getTransferDataFlavors /** * Returns the data encapsulated in this {@link TransferableObject}. * If the {@link Fetcher} constructor was used, then this is when * the {@link Fetcher#getObject getObject()} method will be called. * If the requested data flavor is not supported, then the {@link Fetcher#getObject getObject()} method will not be called. * * @param flavor * The data flavor for the data to return * @return The dropped data * @since 1.1 */ @Override public Object getTransferData(java.awt.datatransfer.DataFlavor flavor) throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException { // Native object if (flavor.equals(DATA_FLAVOR)) { return fetcher == null ? data : fetcher.getObject(); } // String if (flavor.equals(java.awt.datatransfer.DataFlavor.stringFlavor)) { return fetcher == null ? data.toString() : fetcher.getObject().toString(); } // We can't do anything else throw new java.awt.datatransfer.UnsupportedFlavorException(flavor); } // end getTransferData /** * Returns true if flavor is one of the supported * flavors. Flavors are supported using the equals(...) method. * * @param flavor * The data flavor to check * @return Whether or not the flavor is supported * @since 1.1 */ @Override public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) { // Native object if (flavor.equals(DATA_FLAVOR)) { return true; } // String if (flavor.equals(java.awt.datatransfer.DataFlavor.stringFlavor)) { return true; } // We can't do anything else return false; } // end isDataFlavorSupported /* ******** I N N E R I N T E R F A C E F E T C H E R ******** */ /** * Instead of passing your data directly to the {@link TransferableObject} constructor, you may want to know exactly when your data was received * in case you need to remove it from its source (or do anyting else to it). * When the {@link #getTransferData getTransferData(...)} method is called * on the {@link TransferableObject}, the {@link Fetcher}'s {@link #getObject getObject()} method will be called. * * @author Robert Harder * @copyright 2001 * @version 1.1 * @since 1.1 */ public static interface Fetcher { /** * Return the object being encapsulated in the {@link TransferableObject}. * * @return The dropped object * @since 1.1 */ public abstract Object getObject(); } // end inner interface Fetcher } // end class TransferableObject } // end class FileDrop umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/SearchListener.java0000644000175000017500000000260612533641120026264 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import javax.swing.JTextField; import com.baselet.control.constants.Constants; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.Search; public class SearchListener implements KeyListener, MouseMotionListener { public SearchListener() {} @Override public void keyPressed(KeyEvent arg0) { } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { JTextField search = (JTextField) e.getComponent(); DiagramHandler h = CurrentDiagram.getInstance().getDiagramHandler(); if (h != null && search != null && !"".equals(search.getText())) { h.getController().executeCommand(new Search(search.getText())); } CurrentGui.getInstance().getGui().enableSearch(false); } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { CurrentGui.getInstance().getGui().enableSearch(false); } } @Override public void keyTyped(KeyEvent arg0) {} @Override public void mouseDragged(MouseEvent me) {} @Override public void mouseMoved(MouseEvent me) { CurrentGui.getInstance().getGui().setCursor(Constants.TEXT_CURSOR); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/FileDropListener.java0000644000175000017500000000202312533641120026554 0ustar benbenpackage com.baselet.gui.standalone; import java.io.File; import java.io.IOException; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.generator.ClassDiagramConverter; public class FileDropListener implements FileDrop.Listener { private static final Logger log = Logger.getLogger(FileDropListener.class); @Override public void filesDropped(File[] files) { for (File file : files) { try { String filename = file.getCanonicalPath(); if (isJavaFile(filename)) { new ClassDiagramConverter().createClassDiagram(filename); } else { Main.getInstance().doOpen(filename); } } catch (IOException e) { log.error("Cannot open file dropped"); } } } private boolean isJavaFile(String filename) { int dotPosition = filename.lastIndexOf("."); String extension = filename.substring(dotPosition + 1, filename.length()); if (extension.equals("class") || extension.equals("java")) { return true; } return false; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/StandaloneGUIBuilder.java0000644000175000017500000001421712533641120027316 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import javax.imageio.ImageIO; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.ToolTipManager; import javax.swing.WindowConstants; import com.baselet.control.config.Config; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.util.Path; import com.baselet.gui.BaseGUIBuilder; import com.baselet.gui.listener.GUIListener; public class StandaloneGUIBuilder extends BaseGUIBuilder { private JComboBox zoomComboBox; private ZoomListener zoomListener; private JTextField searchField; private JTabbedPane diagramtabs; private JToggleButton mailButton; public JTabbedPane getDiagramtabs() { return diagramtabs; } public JComboBox getZoomComboBox() { return zoomComboBox; } public ZoomListener getZoomListener() { return zoomListener; } public JTextField getSearchField() { return searchField; } public JFrame initSwingGui(MenuBuilder menuBuilder) { JFrame mainFrame = new JFrame(); mainFrame.addKeyListener(new GUIListener()); mainFrame.addKeyListener(new SearchKeyListener()); mainFrame.addWindowListener(new SwingWindowListener()); mainFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // closing is handled in the StandaloneGUI.closeWindow() callback (fix for issue #250) mainFrame.setBounds(Config.getInstance().getProgram_location().x, Config.getInstance().getProgram_location().y, Config.getInstance().getProgram_size().width, Config.getInstance().getProgram_size().height); mainFrame.setTitle(Program.getInstance().getProgramName() + " - Free UML Tool for Fast UML Diagrams"); setImage(mainFrame); if (Config.getInstance().isStart_maximized()) { // If Main starts maximized we set fixed bounds and must set the frame visible // now to avoid a bug where the right sidebar doesn't have the correct size mainFrame.setExtendedState(mainFrame.getExtendedState() | Frame.MAXIMIZED_BOTH); mainFrame.setVisible(true); } mainFrame.setJMenuBar(menuBuilder.createMenu(createSearchPanel(), createZoomPanel(), createMailButton())); JPanel diagramTabPanel = createDiagramTabPanel(); int mainDividerLoc = Math.min(mainFrame.getSize().width - Constants.MIN_MAIN_SPLITPANEL_SIZE, Config.getInstance().getMain_split_position()); JSplitPane baseSplitPane = initBase(diagramTabPanel, mainDividerLoc); mainFrame.add(baseSplitPane); ToolTipManager.sharedInstance().setInitialDelay(100); mainFrame.setVisible(true); return mainFrame; } private void setImage(JFrame mainFrame) { try { ArrayList images = new ArrayList(); for (Integer i : new int[] { 16, 20, 24, 32, 40, 48, 64 }) { File file = new File(Path.homeProgram() + "img/" + Program.getInstance().getProgramName().toLowerCase() + "_logo" + i + ".png"); images.add(ImageIO.read(file)); } mainFrame.setIconImages(images); } catch (IOException e) { throw new RuntimeException(e); } } private void createZoomComboBox() { zoomComboBox = new JComboBox(); zoomComboBox.setPreferredSize(new Dimension(80, 24)); zoomComboBox.setMinimumSize(zoomComboBox.getPreferredSize()); zoomComboBox.setMaximumSize(zoomComboBox.getPreferredSize()); zoomListener = new ZoomListener(); zoomComboBox.addActionListener(zoomListener); zoomComboBox.addMouseWheelListener(zoomListener); zoomComboBox.setToolTipText("Use ± or mouse wheel to zoom"); String[] zoomValues = Constants.zoomValueList.toArray(new String[Constants.zoomValueList.size()]); zoomComboBox.setModel(new DefaultComboBoxModel(zoomValues)); zoomComboBox.setSelectedIndex(9); } public JPanel createZoomPanel() { createZoomComboBox(); JPanel zoomPanel = new JPanel(); zoomPanel.setOpaque(false); zoomPanel.setLayout(new BoxLayout(zoomPanel, BoxLayout.X_AXIS)); zoomPanel.add(new JLabel("Zoom: ")); zoomPanel.add(zoomComboBox); zoomPanel.add(Box.createRigidArea(new Dimension(20, 0))); return zoomPanel; } private void createSearchField() { searchField = new JTextField(10); searchField.setMinimumSize(searchField.getPreferredSize()); searchField.setMaximumSize(searchField.getPreferredSize()); searchField.addKeyListener(new SearchListener()); } public JPanel createSearchPanel() { createSearchField(); JPanel searchPanel = new JPanel(); searchPanel.setOpaque(false); searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.X_AXIS)); searchPanel.add(Box.createRigidArea(new Dimension(50, 0))); searchPanel.add(new JLabel("Search: ")); searchPanel.add(searchField); searchPanel.add(Box.createRigidArea(new Dimension(20, 0))); return searchPanel; } @SuppressWarnings("unused") public JPanel createDiagramTabPanel() { JPanel diagramspanel = new JPanel(); new FileDrop(diagramspanel, new FileDropListener()); // enable drag&drop from desktop into diagrampanel diagramtabs = new JTabbedPane(); diagramtabs.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); diagramspanel.setLayout(new GridLayout(1, 1)); diagramspanel.add(diagramtabs); return diagramspanel; } public JToggleButton createMailButton() { mailButton = new JToggleButton("Mail diagram"); mailButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setMailPanelEnabled(!getMailPanel().isVisible()); } }); return mailButton; } @Override public void setMailPanelEnabled(boolean enable) { super.setMailPanelEnabled(enable); mailButton.setSelected(enable); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/StandaloneGUI.java0000644000175000017500000002063212533641120026005 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.Component; import java.awt.Cursor; import java.awt.Frame; import java.util.Collection; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import org.apache.log4j.Logger; import com.baselet.control.CanCloseProgram; import com.baselet.control.Main; import com.baselet.control.config.Config; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElementHandler; import com.baselet.gui.BaseGUI; import com.baselet.gui.pane.OwnSyntaxPane; public class StandaloneGUI extends BaseGUI { private final Logger log = Logger.getLogger(StandaloneGUI.class); private JFrame mainFrame; private final MenuBuilder menuBuilder = new MenuBuilder(); private final StandaloneGUIBuilder guiBuilder = new StandaloneGUIBuilder(); public StandaloneGUI(CanCloseProgram main) { super(main); } @Override public void updateDiagramName(DiagramHandler diagram, String name) { JTabbedPane diagramtabs = guiBuilder.getDiagramtabs(); int index = diagramtabs.indexOfComponent(diagram.getDrawPanel().getScrollPane()); if (index != -1) { diagramtabs.setTitleAt(index, name); // update only selected tab to keep scrolling tab position ((TabComponent) diagramtabs.getTabComponentAt(index)).updateUI(); } } @Override public void setDiagramChanged(DiagramHandler diagram, boolean changed) { String change_string = ""; if (changed) { change_string = " *"; } updateDiagramName(diagram, diagram.getName() + change_string); } @Override public void setCustomElementChanged(CustomElementHandler handler, boolean changed) { } @Override public void closeWindow() { guiBuilder.getMailPanel().closePanel(); // We must close the mailpanel to save the input date if (askSaveForAllDirtyDiagrams()) { main.closeProgram(); System.exit(0); // issue #250: handle closing using a listener (see also handle closing using a listener (see also https://stackoverflow.com/questions/246228/why-does-my-application-still-run-after-closing-main-window) } } private boolean askSaveForAllDirtyDiagrams() { boolean ok = true; for (DiagramHandler d : Main.getInstance().getDiagrams()) { if (!d.askSaveIfDirty()) { ok = false; } } if (!getCurrentCustomHandler().closeEntity()) { ok = false; } return ok; } @Override protected void init() { mainFrame = guiBuilder.initSwingGui(menuBuilder); } @Override public void showPalette(String palette) { super.showPalette(palette); guiBuilder.setPaletteActive(palette); } @Override public String getSelectedPalette() { return guiBuilder.getPaletteList().getSelectedItem().toString(); } @Override public void close(DiagramHandler diagram) { guiBuilder.getDiagramtabs().remove(diagram.getDrawPanel().getScrollPane()); DrawPanel p = getCurrentDiagram(); if (p != null) { CurrentDiagram.getInstance().setCurrentDiagramHandler(p.getHandler()); } else { CurrentDiagram.getInstance().setCurrentDiagramHandler(null); } } @Override public void open(DiagramHandler diagram) { JTabbedPane diagramtabs = guiBuilder.getDiagramtabs(); diagramtabs.add(diagram.getName(), diagram.getDrawPanel().getScrollPane()); diagramtabs.setTabComponentAt(diagramtabs.getTabCount() - 1, new TabComponent(diagramtabs, diagram)); jumpTo(diagram); } @Override public void jumpTo(DiagramHandler diagram) { guiBuilder.getDiagramtabs().setSelectedComponent(diagram.getDrawPanel().getScrollPane()); diagram.getDrawPanel().getSelector().updateSelectorInformation(); DrawPanel p = getCurrentDiagram(); if (p != null) { CurrentDiagram.getInstance().setCurrentDiagramHandler(p.getHandler()); } else { CurrentDiagram.getInstance().setCurrentDiagramHandler(null); } } @Override public DrawPanel getCurrentDiagram() { JScrollPane scr = (JScrollPane) guiBuilder.getDiagramtabs().getSelectedComponent(); if (scr != null) { return (DrawPanel) scr.getViewport().getView(); } else { return null; } } @Override public void elementsSelected(Collection selectedElements) { super.elementsSelected(selectedElements); menuBuilder.elementsSelected(selectedElements); } @Override public void enablePasteMenuEntry() { menuBuilder.enablePasteMenuEntry(); } @Override public void setCustomPanelEnabled(boolean enable) { guiBuilder.setCustomPanelEnabled(enable); menuBuilder.setNewCustomElementMenuItemsEnabled(!enable); // disable "New" menu items if panel is visible setDrawPanelEnabled(!enable); } private void setDrawPanelEnabled(boolean enable) { JTabbedPane diagramtabs = guiBuilder.getDiagramtabs(); guiBuilder.getPalettePanel().setEnabled(enable); for (Component c : guiBuilder.getPalettePanel().getComponents()) { c.setEnabled(enable); } diagramtabs.setEnabled(enable); for (Component c : diagramtabs.getComponents()) { c.setEnabled(enable); } for (int i = 0; i < diagramtabs.getTabCount(); i++) { diagramtabs.getTabComponentAt(i).setEnabled(enable); } guiBuilder.getSearchField().setEnabled(enable); } @Override public void setMailPanelEnabled(boolean enable) { guiBuilder.setMailPanelEnabled(enable); } @Override public boolean isMailPanelVisible() { return guiBuilder.getMailPanel().isVisible(); } @Override public void setCustomElementSelected(boolean selected) { // Custom Element Edit is only enabled if a CE is selected and the panel is not visible menuBuilder.setEditCustomElementMenuItemEnabled(selected && !guiBuilder.getCustomPanel().isVisible()); } @Override public void diagramSelected(DiagramHandler handler) { updateGrayedOutMenuItems(handler); } @Override public void updateGrayedOutMenuItems(DiagramHandler handler) { menuBuilder.updateGrayedOutMenuItems(handler); } @Override public void enableSearch(boolean enable) { guiBuilder.getSearchField().requestFocus(); } @Override public int getMainSplitPosition() { return guiBuilder.getMainSplit().getDividerLocation(); } @Override public int getRightSplitPosition() { return guiBuilder.getRightSplit().getDividerLocation(); } @Override public int getMailSplitPosition() { return Config.getInstance().getMail_split_position(); // must return stored value in Constants, otherwise 0 will be returned in case of a closed panel } @Override public Frame getMainFrame() { return mainFrame; } @Override public CustomElementHandler getCurrentCustomHandler() { return guiBuilder.getCustomHandler(); } @Override public OwnSyntaxPane getPropertyPane() { return guiBuilder.getPropertyTextPane(); } @Override public void setValueOfZoomDisplay(int i) { JComboBox zoomComboBox = guiBuilder.getZoomComboBox(); // This method should just set the value without ActionEvent therefore we remove the listener temporarily if (zoomComboBox != null) { zoomComboBox.removeActionListener(guiBuilder.getZoomListener()); zoomComboBox.setSelectedIndex(i - 1); zoomComboBox.addActionListener(guiBuilder.getZoomListener()); } } @Override public void focusPropertyPane() { guiBuilder.getPropertyTextPane().getTextComponent().requestFocus(); } @Override public void setCursor(Cursor cursor) { if (mainFrame != null) { mainFrame.setCursor(cursor); } } @Override public void requestFocus() { mainFrame.requestFocus(); } @Override public void setLookAndFeel(String newui, JFrame optionframe) { try { Frame topFrame = getMainFrame(); UIManager.setLookAndFeel(newui); SwingUtilities.updateComponentTreeUI(topFrame); SwingUtilities.updateComponentTreeUI(optionframe); topFrame.pack(); optionframe.pack(); } catch (ClassNotFoundException e) { log.error("Cannot set LookAndFeel", e); } catch (InstantiationException e) { log.error("Cannot set LookAndFeel", e); } catch (IllegalAccessException e) { log.error("Cannot set LookAndFeel", e); } catch (UnsupportedLookAndFeelException e) { log.error("Cannot set LookAndFeel", e); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/SwingWindowListener.java0000644000175000017500000000134312533641120027333 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.event.WindowEvent; import com.baselet.gui.CurrentGui; public class SwingWindowListener implements java.awt.event.WindowListener { public SwingWindowListener() {} @Override public void windowActivated(WindowEvent arg0) {} @Override public void windowClosed(WindowEvent arg0) {} @Override public void windowClosing(WindowEvent arg0) { CurrentGui.getInstance().getGui().closeWindow(); } @Override public void windowDeactivated(WindowEvent arg0) {} @Override public void windowDeiconified(WindowEvent arg0) {} @Override public void windowIconified(WindowEvent arg0) {} @Override public void windowOpened(WindowEvent arg0) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/SearchKeyListener.java0000644000175000017500000000121712533641120026732 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import com.baselet.control.constants.SystemInfo; import com.baselet.gui.CurrentGui; public class SearchKeyListener implements KeyListener { @Override public void keyPressed(KeyEvent e) { boolean meta_f_pressed = e.getKeyCode() == KeyEvent.VK_F && (e.getModifiers() & SystemInfo.META_KEY.getMask()) != 0; if (meta_f_pressed || e.getKeyChar() == '/') { CurrentGui.getInstance().getGui().enableSearch(true); } } @Override public void keyTyped(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/standalone/TabListener.java0000644000175000017500000000212312533641120025557 0ustar benbenpackage com.baselet.gui.standalone; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JTabbedPane; import com.baselet.diagram.DiagramHandler; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; public class TabListener implements MouseListener { private DiagramHandler handler; private JTabbedPane pane; public TabListener(DiagramHandler handler, JTabbedPane pane) { this.handler = handler; this.pane = pane; } @Override public void mouseClicked(MouseEvent arg0) { } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { pane.setSelectedComponent(handler.getDrawPanel().getScrollPane()); handler.getDrawPanel().getSelector().updateSelectorInformation(); BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null) { gui.setValueOfZoomDisplay(handler.getGridSize()); } } @Override public void mouseReleased(MouseEvent arg0) { } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/MailPanel.java0000644000175000017500000004712612533641120023071 0ustar benbenpackage com.baselet.gui; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.UIManager; import org.apache.log4j.Logger; import com.baselet.control.config.Config; import com.baselet.control.config.ConfigMail; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.util.Utils; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.io.DiagramFileHandler; public class MailPanel extends JPanel { private static final Logger log = Logger.getLogger(MailPanel.class); private static final long serialVersionUID = 1L; /** * Some int and String */ private final int paddingTop = 1; private final int paddingBottom = 1; private final int outerPaddingLeft = 15; private final int outerPaddingRight = 15; private final int halfHorizontalDividerSpace = 2; private final int verticalDividerSpace = 10; /** * Components */ private final GridBagLayout layout = new GridBagLayout(); private final JLabel lb_from = new JLabel("From:"); private final JTextField tf_from = new JTextField(); private final JLink lnk_smtpInfo = new JLink(Program.getInstance().getWebsite() + "/smtp.htm", "What is SMTP?"); private final JLabel lb_smtp = new JLabel("SMTP:"); private final JTextField tf_smtp = new JTextField(); private final JCheckBox cb_smtp_auth = new JCheckBox(); private final JLabel lb_smtpUser = new JLabel("User:"); private final JTextField tf_smtpUser = new JTextField(); private final JLabel lb_smtpPW = new JLabel("PW:"); private final JPasswordField pf_smtpPW = new JPasswordField(); private final JCheckBox cb_pwSave = new JCheckBox(); private final JLabel lb_to = new JLabel("To:"); private final JTextField tf_to = new JTextField(); private final JLabel lb_cc = new JLabel("CC:"); private final JTextField tf_cc = new JTextField(); private final JLabel lb_bcc = new JLabel("BCC:"); private final JTextField tf_bcc = new JTextField(); private final JLabel lb_subject = new JLabel("Subject:"); private final JTextField tf_subject = new JTextField(); private final JTextArea ta_text = new JTextArea(5, 5); JScrollPane sp_text = new JScrollPane(ta_text); private final JCheckBox cb_attachXml = new JCheckBox(); private final JCheckBox cb_attachGif = new JCheckBox(); private final JCheckBox cb_attachPdf = new JCheckBox(); private final JButton bt_send = new JButton("Send"); private final JButton bt_cancel = new JButton("Cancel"); private final JPanel panel_attachments = new JPanel(new FlowLayout(FlowLayout.LEFT)); private final JPanel panel_attachmentsWithButton = new JPanel(layout); // the padding between lines is different for the labels and text components of the grid bag layout private final Insets paddingLeftLabel = new Insets(paddingTop, outerPaddingLeft, paddingBottom, halfHorizontalDividerSpace); private final Insets paddingMessagebox = new Insets(paddingTop, outerPaddingLeft, paddingBottom, outerPaddingRight); private final Insets paddingText = new Insets(paddingTop, halfHorizontalDividerSpace, paddingBottom, outerPaddingRight); private final Insets paddingCheckbox = new Insets(paddingTop - 2, halfHorizontalDividerSpace, paddingBottom - 2, outerPaddingRight); private final Insets paddingRightLabel = new Insets(paddingTop, halfHorizontalDividerSpace, paddingBottom, halfHorizontalDividerSpace); private final Insets noPadding = new Insets(0, 0, 0, 0); // the label doesn't get any additional space. it's always as short as possible private final double noWeight = 0; private final double fullWeight = 1; private final double leftWeight = 0.75; private final double rightWeight = 0.25; // the constraint int to fill the width private final int fillWidth = GridBagConstraints.HORIZONTAL; private final int fillBoth = GridBagConstraints.BOTH; public MailPanel() { initAndFillComponents(); setLayout(layout); setSize(new Dimension(0, Config.getInstance().getMail_split_position())); int line = 0; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 10, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, lb_to, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_to, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_from, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_from, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, lnk_smtpInfo, 4, line, 1, 1, fillWidth, noWeight, 0, paddingText); line++; addComponent(this, layout, lb_cc, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_cc, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtp, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_smtp, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, cb_smtp_auth, 4, line, 1, 1, fillWidth, noWeight, 0, paddingText); line++; addComponent(this, layout, lb_bcc, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_bcc, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtpUser, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_smtpUser, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); line++; addComponent(this, layout, lb_subject, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_subject, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtpPW, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, pf_smtpPW, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, cb_pwSave, 4, line, 1, 1, fillWidth, noWeight, 0, paddingCheckbox); line++; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 10, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, sp_text, 0, line, 5, 1, fillBoth, leftWeight, 1, paddingMessagebox); line++; addComponent(this, layout, panel_attachmentsWithButton, 1, line, 5, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 4, 1, fillWidth, fullWeight, 0, noPadding); } private void initAndFillComponents() { ta_text.setText(Constants.getDefaultMailtext()); cb_pwSave.setText("save in config"); cb_attachXml.setText("attach " + Program.getInstance().getExtension().toUpperCase()); cb_attachGif.setText("attach GIF"); cb_attachPdf.setText("attach PDF"); cb_smtp_auth.setText("authentication"); bt_send.addActionListener(new SendActionListener()); bt_cancel.addActionListener(new CancelActionListener()); cb_smtp_auth.addActionListener(new AuthentificationActionListener()); // Set Tooltips String adressToolTip = "Separate multiple adresses with ','"; cb_pwSave.setToolTipText("WARNING: The password is stored as plain text in " + Program.getInstance().getConfigName()); tf_from.setToolTipText(adressToolTip); tf_to.setToolTipText(adressToolTip); tf_cc.setToolTipText(adressToolTip); tf_bcc.setToolTipText(adressToolTip); // Fill Attachment Panel panel_attachments.add(cb_attachXml); panel_attachments.add(Box.createRigidArea(new Dimension(5, 0))); panel_attachments.add(cb_attachGif); panel_attachments.add(Box.createRigidArea(new Dimension(5, 0))); panel_attachments.add(cb_attachPdf); // Fill the superpanel which holds attachments and the send button addComponent(panel_attachmentsWithButton, layout, panel_attachments, 0, 0, 1, 1, fillWidth, fullWeight, 0, noPadding); addComponent(panel_attachmentsWithButton, layout, bt_send, 1, 0, 1, 1, fillWidth, fullWeight, 0, paddingText); addComponent(panel_attachmentsWithButton, layout, bt_cancel, 2, 0, 1, 1, fillWidth, fullWeight, 0, paddingText); setAllFonts(); readConstants(); checkVisibilityOfSmtpAuth(); } private void sendMail() { /** * Initialize some variables and objects */ String smtpHost = tf_smtp.getText(); String smtpUser = tf_smtpUser.getText(); String smtpPW = String.valueOf(pf_smtpPW.getPassword()); String from = tf_from.getText(); String[] to = removeWhitespaceAndSplitAt(tf_to.getText()); String[] cc = removeWhitespaceAndSplitAt(tf_cc.getText()); String[] bcc = removeWhitespaceAndSplitAt(tf_bcc.getText()); String subject = tf_subject.getText(); String text = ta_text.getText(); boolean useSmtpAuthentication = false; File diagramXml = null; File diagramGif = null; File diagramPdf = null; int nrOfAttachments = 0; // Set SMTP Authentication if the user or password field isn't empty if (!smtpUser.isEmpty() || !smtpPW.isEmpty()) { useSmtpAuthentication = true; } // Create the temp diagrams to send try { final String diagramName = "diagram_" + new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date()); DiagramFileHandler fileHandler = CurrentDiagram.getInstance().getDiagramHandler().getFileHandler(); if (cb_attachXml.isSelected()) { nrOfAttachments++; diagramXml = fileHandler.doSaveTempDiagram(diagramName, Program.getInstance().getExtension()); } if (cb_attachGif.isSelected()) { nrOfAttachments++; diagramGif = fileHandler.doSaveTempDiagram(diagramName, "gif"); } if (cb_attachPdf.isSelected()) { nrOfAttachments++; diagramPdf = fileHandler.doSaveTempDiagram(diagramName, "pdf"); } } catch (Exception e) { JOptionPane.showMessageDialog(this, "There has been an error with your diagram. Please make sure it's not empty.", "Diagram Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return; } /** * Check if all necessary fields are filled */ String errorMsg = null; if (smtpHost.isEmpty()) { errorMsg = "The SMTP field must not be empty"; } else if (from.isEmpty()) { errorMsg = "The FROM field must not be empty"; } else if (to.length == 0) { errorMsg = "The TO field must not be empty"; } if (errorMsg != null) { JOptionPane.showMessageDialog(this, errorMsg, "Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return; } /** * Set up the mail */ try { // Get system properties and session Properties props = System.getProperties(); Session session = Session.getInstance(props); // Define message and it's parts MimeMessage message = new MimeMessage(session); MimeBodyPart textPart = new MimeBodyPart(); MimeBodyPart[] attachmentPart = new MimeBodyPart[nrOfAttachments]; for (int i = 0; i < nrOfAttachments; i++) { attachmentPart[i] = new MimeBodyPart(); } // Build multipart message Multipart multipart = new MimeMultipart(); multipart.addBodyPart(textPart); for (int i = 0; i < nrOfAttachments; i++) { multipart.addBodyPart(attachmentPart[i]); } message.setContent(multipart); /** * Fill the message properties */ // Set the SMTP Host props.put("mail.smtp.host", smtpHost); // We want to close the connection immediately after sending props.put("mail.smtp.quitwait", "false"); // We want to use encryption if needed props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.ssl.protocols", "SSLv3 TLSv1"); // If authentication is needed we set it to true if (useSmtpAuthentication) { props.put("mail.smtp.auth", "true"); } else { props.put("mail.smtp.auth", "false"); } // Set all recipients of any kind (TO, CC, BCC) message.setFrom(new InternetAddress(from)); for (String element : to) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(element)); } for (String element : cc) { message.addRecipient(Message.RecipientType.CC, new InternetAddress(element)); } for (String element : bcc) { message.addRecipient(Message.RecipientType.BCC, new InternetAddress(element)); } // Set subject, text and attachment message.setSubject(subject); textPart.setText(text); int i = 0; if (cb_attachXml.isSelected()) { attachmentPart[i++].attachFile(diagramXml); } if (cb_attachGif.isSelected()) { attachmentPart[i++].attachFile(diagramGif); } if (cb_attachPdf.isSelected()) { attachmentPart[i++].attachFile(diagramPdf); } /** * Send message (if no authentication is used, we use the short variant to send a mail */ if (useSmtpAuthentication) { Transport transport = session.getTransport("smtp"); try { transport.connect(smtpHost, smtpUser, smtpPW); transport.sendMessage(message, message.getAllRecipients()); } finally { transport.close(); } } else { // No SMTP Authentication Transport.send(message); } closePanel(); } catch (MessagingException e) { log.error("SMTP Error", e); JOptionPane.showMessageDialog(this, "There has been an error with your smtp server." + Constants.NEWLINE + "Please recheck your smtp server and login data.", "SMTP Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } catch (IOException e) { log.error("Mail Error", e); JOptionPane.showMessageDialog(this, "There has been an error sending your mail." + Constants.NEWLINE + "Please recheck your input data.", "Sending Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } finally { if (diagramXml != null) { Utils.safeDeleteFile(diagramXml, false); } if (diagramGif != null) { Utils.safeDeleteFile(diagramGif, false); } if (diagramPdf != null) { Utils.safeDeleteFile(diagramPdf, false); } } } /** * Adds a component to this panel * * @param gbl * The GridBagLayout of this component * @param c * The Component to add * @param x * The x value of grid where the component starts * @param y * The y value of grid where the component starts * @param width * How many spaces of the grid's width will be used by the component * @param height * How many spaces of the grid's height will be used by the component * @param fill * If the component's display area is larger than the component's requested size this param determines whether and how to resize the component * @param weightx * Specifies how to distribute extra horizontal space. * @param weighty * Specifies how to distribute extra vertical space. * @param insets * Specifies the external padding of the component (= minimum amount of space between the component and the edges of its display area) */ private void addComponent(JPanel panel, GridBagLayout gbl, Component c, int x, int y, int width, int height, int fill, double weightx, double weighty, Insets insets) { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = width; gbc.gridheight = height; gbc.fill = fill; gbc.weightx = weightx; gbc.weighty = weighty; gbc.insets = insets; gbl.setConstraints(c, gbc); panel.add(c); } private String[] removeWhitespaceAndSplitAt(String inputString) { if (inputString.isEmpty()) { return new String[] {}; } StringBuilder sb = new StringBuilder(""); for (int i = 0; i < inputString.length(); i++) { if (inputString.charAt(i) != ' ') { sb.append(inputString.charAt(i)); } } return sb.toString().split(","); } private void storeConstants() { ConfigMail cfgMail = ConfigMail.getInstance(); cfgMail.setMail_smtp(tf_smtp.getText()); cfgMail.setMail_smtp_auth(cb_smtp_auth.isSelected()); cfgMail.setMail_smtp_user(tf_smtpUser.getText()); cfgMail.setMail_smtp_pw_store(cb_pwSave.isSelected()); if (cb_pwSave.isSelected()) { cfgMail.setMail_smtp_pw(String.valueOf(pf_smtpPW.getPassword())); } else { cfgMail.setMail_smtp_pw(""); } cfgMail.setMail_from(tf_from.getText()); cfgMail.setMail_to(tf_to.getText()); cfgMail.setMail_cc(tf_cc.getText()); cfgMail.setMail_bcc(tf_bcc.getText()); cfgMail.setMail_xml(cb_attachXml.isSelected()); cfgMail.setMail_gif(cb_attachGif.isSelected()); cfgMail.setMail_pdf(cb_attachPdf.isSelected()); } private void readConstants() { ConfigMail cfgMail = ConfigMail.getInstance(); tf_smtp.setText(cfgMail.getMail_smtp()); cb_smtp_auth.setSelected(cfgMail.isMail_smtp_auth()); tf_smtpUser.setText(cfgMail.getMail_smtp_user()); cb_pwSave.setSelected(cfgMail.isMail_smtp_pw_store()); pf_smtpPW.setText(cfgMail.getMail_smtp_pw()); tf_from.setText(cfgMail.getMail_from()); tf_to.setText(cfgMail.getMail_to()); tf_cc.setText(cfgMail.getMail_cc()); tf_bcc.setText(cfgMail.getMail_bcc()); cb_attachXml.setSelected(cfgMail.isMail_xml()); cb_attachGif.setSelected(cfgMail.isMail_gif()); cb_attachPdf.setSelected(cfgMail.isMail_pdf()); } private void setAllFonts() { Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12); Font fontBold = new Font(Font.SANS_SERIF, Font.BOLD, 12); Font fontSmallItalic = new Font(Font.SANS_SERIF, Font.ITALIC, 10); lb_smtp.setFont(fontBold); tf_smtp.setFont(font); lb_smtpUser.setFont(fontBold); tf_smtpUser.setFont(font); lb_smtpPW.setFont(fontBold); pf_smtpPW.setFont(font); lb_from.setFont(fontBold); tf_from.setFont(font); lb_to.setFont(fontBold); tf_to.setFont(font); lb_cc.setFont(fontBold); tf_cc.setFont(font); lb_bcc.setFont(fontBold); tf_bcc.setFont(font); lb_subject.setFont(fontBold); tf_subject.setFont(font); ta_text.setFont(font); cb_attachXml.setFont(fontBold); cb_attachGif.setFont(fontBold); cb_attachPdf.setFont(fontBold); lnk_smtpInfo.setFont(fontSmallItalic); cb_smtp_auth.setFont(fontSmallItalic); cb_pwSave.setFont(fontSmallItalic); } public void closePanel() { storeConstants(); Config.getInstance().setMail_split_position((int) this.getSize().getHeight()); CurrentGui.getInstance().getGui().setMailPanelEnabled(false); } private class SendActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { sendMail(); } } private class CancelActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { closePanel(); } } private void checkVisibilityOfSmtpAuth() { boolean val = cb_smtp_auth.isSelected(); lb_smtpUser.setVisible(val); tf_smtpUser.setVisible(val); lb_smtpPW.setVisible(val); pf_smtpPW.setVisible(val); cb_pwSave.setVisible(val); if (!val) { tf_smtpUser.setText(""); pf_smtpPW.setText(""); cb_pwSave.setSelected(false); } repaint(); } private class AuthentificationActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { checkVisibilityOfSmtpAuth(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/BrowserLauncher.java0000644000175000017500000000421412533641120024323 0ustar benbenpackage com.baselet.gui; import java.awt.Desktop; import java.io.IOException; import java.lang.reflect.Method; import java.net.URI; import java.net.URL; import java.util.Scanner; import org.apache.log4j.Logger; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Os; public class BrowserLauncher { private static final Logger log = Logger.getLogger(BrowserLauncher.class); public static void openURL(String url) { try { // Since Java6 this is a much easier method to open the browser if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); desktop.browse(new URI(url)); } // Only if desktop is not supported we try the old main specific code else { if (SystemInfo.OS == Os.MAC) { Class fileMgr = Class.forName("com.apple.eio.FileManager"); Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class }); openURL.invoke(null, new Object[] { url }); } else if (SystemInfo.OS == Os.WINDOWS) { Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url); } else { // assume Unix or Linux String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" }; String browser = null; for (int count = 0; count < browsers.length && browser == null; count++) { if (Runtime.getRuntime().exec(new String[] { "which", browsers[count] }).waitFor() == 0) { browser = browsers[count]; } } if (browser == null) { throw new Exception("Could not find web browser"); } else { Runtime.getRuntime().exec(new String[] { browser, url }); } } } } catch (Exception e) { log.error("Error at opening the URL.", e); } } public static String readURL(String url) throws IOException { StringBuilder sb = new StringBuilder(""); Scanner sc = null; try { sc = new Scanner(new URL(url).openStream()); while (sc.hasNextLine()) { sb.append(sc.nextLine()).append("\n"); } } finally { if (sc != null) { sc.close(); } } return sb.toString(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/0000755000175000017500000000000012533641120021770 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Copy.java0000644000175000017500000000155012533641120023546 0ustar benbenpackage com.baselet.gui.command; import java.util.List; import com.baselet.diagram.DiagramHandler; import com.baselet.element.ElementFactorySwing; import com.baselet.element.interfaces.GridElement; public class Copy extends Command { @Override public void execute(DiagramHandler handler) { // dont execute super.execute() because no change of diagram is required. List entities = ElementFactorySwing.createCopy(handler.getDrawPanel().getSelector().getSelectedElements()); // if no element is selected, the whole diagram is copied into the clipboard if (entities.isEmpty()) { entities = ElementFactorySwing.createCopy(handler.getDrawPanel().getGridElements()); } ClipBoard.getInstance().copyAndZoomToDefaultLevel(entities, handler); } @Override public boolean isChangingDiagram() { return false; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Paste.java0000644000175000017500000000576712533641120023726 0ustar benbenpackage com.baselet.gui.command; import java.awt.Point; import java.util.Vector; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.element.ElementFactorySwing; import com.baselet.element.Selector; import com.baselet.element.interfaces.GridElement; public class Paste extends Command { private Point origin; private Vector entities; private int viewpX = 0; private int viewpY = 0; @Override public void execute(DiagramHandler handler) { super.execute(handler); if (entities == null) { entities = new Vector(); for (GridElement e : ClipBoard.getInstance().paste()) { GridElement clone = ElementFactorySwing.createCopy(e, handler); entities.add(clone); } Selector.replaceGroupsWithNewGroups(entities, handler.getDrawPanel().getSelector()); } // AB: first execution of paste if (origin == null) { origin = handler.getDrawPanel().getOriginAtDefaultZoom(); // AB: Include viewport position to paste on visible area Point viewp = handler.getDrawPanel().getScrollPane().getViewport().getViewPosition(); viewpX = handler.realignToGrid(false, (int) viewp.getX()) / handler.getGridSize(); viewpY = handler.realignToGrid(false, (int) viewp.getY()) / handler.getGridSize(); } if (entities.isEmpty()) { return; } DiagramHandler.zoomEntities(Constants.DEFAULTGRIDSIZE, handler.getGridSize(), entities); // Calculate the rectangle around the copied entities int minX = Integer.MAX_VALUE; int minY = Integer.MAX_VALUE; for (GridElement e : entities) { minX = Math.min(e.getRectangle().x, minX); minY = Math.min(e.getRectangle().y, minY); } for (GridElement e : entities) { e.setLocationDifference( viewpX * handler.getGridSize() - minX + handler.getGridSize() * Constants.PASTE_DISPLACEMENT_GRIDS, viewpY * handler.getGridSize() - minY + handler.getGridSize() * Constants.PASTE_DISPLACEMENT_GRIDS); } int offsetX = origin.x - handler.getDrawPanel().getOriginAtDefaultZoom().x; int offsetY = origin.y - handler.getDrawPanel().getOriginAtDefaultZoom().y; offsetX = offsetX * handler.getGridSize() / Constants.DEFAULTGRIDSIZE; offsetY = offsetY * handler.getGridSize() / Constants.DEFAULTGRIDSIZE; for (GridElement e : entities) { new AddElement(e, handler.realignToGrid(e.getRectangle().x + offsetX), handler.realignToGrid(e.getRectangle().y + offsetY), false).execute(handler); } handler.getDrawPanel().getSelector().deselectAll(); for (GridElement e : entities) { handler.getDrawPanel().getSelector().select(e); } handler.getDrawPanel().updatePanelAndScrollbars(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); DiagramHandler.zoomEntities(handler.getGridSize(), Constants.DEFAULTGRIDSIZE, entities); new RemoveElement(entities, false).execute(handler); handler.getDrawPanel().updatePanelAndScrollbars(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Controller.java0000644000175000017500000000420112533641120024753 0ustar benbenpackage com.baselet.gui.command; import java.util.Vector; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.gui.CurrentGui; public class Controller { private Vector commands; private final DiagramHandler handler; private int _cursor; public Controller(DiagramHandler handler) { commands = new Vector(); _cursor = -1; this.handler = handler; } public void executeCommand(Command newCommand) { // Remove future commands for (int i = commands.size() - 1; i > _cursor; i--) { commands.removeElementAt(i); } commands.add(newCommand); newCommand.execute(handler); if (commands.size() >= 2) { Command c_n, c_nMinus1; c_n = commands.elementAt(commands.size() - 1); c_nMinus1 = commands.elementAt(commands.size() - 2); if (c_n.isMergeableTo(c_nMinus1)) { commands.removeElement(c_n); commands.removeElement(c_nMinus1); Command c = c_n.mergeTo(c_nMinus1); commands.add(c); } } _cursor = commands.size() - 1; if (newCommand.isChangingDiagram()) { handler.setChanged(true); } CurrentGui.getInstance().getGui().updateGrayedOutMenuItems(handler); } public void undo() { if (isUndoable()) { Command c = commands.elementAt(_cursor); c.undo(handler); _cursor--; if (c.isChangingDiagram()) { handler.setChanged(true); } } CurrentGui.getInstance().getGui().updateGrayedOutMenuItems(CurrentDiagram.getInstance().getDiagramHandler()); } public void redo() { if (isRedoable()) { Command c = commands.elementAt(_cursor + 1); c.redo(handler); _cursor++; if (c.isChangingDiagram()) { handler.setChanged(true); } } CurrentGui.getInstance().getGui().updateGrayedOutMenuItems(CurrentDiagram.getInstance().getDiagramHandler()); } public boolean isEmpty() { return commands.isEmpty(); } public boolean isUndoable() { return _cursor >= 0; } public boolean isRedoable() { return _cursor < commands.size() - 1; } public void clear() { commands = new Vector(); _cursor = -1; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/HelpPanelChanged.java0000644000175000017500000000462512533641120025764 0ustar benbenpackage com.baselet.gui.command; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.baselet.control.constants.Constants; import com.baselet.control.util.Utils; import com.baselet.diagram.DiagramHandler; public class HelpPanelChanged extends Command { private final String changed_to; private String changed_from; public HelpPanelChanged(String text) { changed_to = text; } private HelpPanelChanged(String changed_from, String changed_to) { this.changed_from = changed_from; this.changed_to = changed_to; } public static Double getFontsize(String text) { if (text == null) { return null; } Pattern p = Pattern.compile("fontsize=" + Constants.REGEX_FLOAT + "( .*)?"); Vector txt = Utils.decomposeStrings(text); for (String t : txt) { Matcher m = p.matcher(t); if (m.matches()) { return Double.parseDouble(m.group(1)); } } return null; } public static String getFontfamily(String text) { if (text == null) { return null; } Pattern p = Pattern.compile("fontfamily\\=(\\w+).*"); Vector txt = Utils.decomposeStrings(text); for (String t : txt) { Matcher m = p.matcher(t); if (m.matches()) { return m.group(1); } } return null; } @Override public void execute(DiagramHandler handler) { super.execute(handler); changed_from = handler.getHelpText(); handler.setHelpText(changed_to); handler.getFontHandler().setDiagramDefaultFontSize(getFontsize(changed_to)); handler.getFontHandler().setDiagramDefaultFontFamily(getFontfamily(changed_to)); handler.getDrawPanel().updateElements(); handler.getDrawPanel().repaint(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); handler.setHelpText(changed_from); handler.getFontHandler().setDiagramDefaultFontSize(getFontsize(changed_from)); handler.getFontHandler().setDiagramDefaultFontFamily(getFontfamily(changed_from)); handler.getDrawPanel().updateElements(); handler.getDrawPanel().repaint(); } @Override public boolean isMergeableTo(Command c) { if (c instanceof HelpPanelChanged) { return true; } return false; } @Override public Command mergeTo(Command c) { HelpPanelChanged tmp = (HelpPanelChanged) c; HelpPanelChanged ret = new HelpPanelChanged(tmp.changed_from, changed_to); return ret; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/ChangeElementSetting.java0000644000175000017500000000356412533641120026700 0ustar benbenpackage com.baselet.gui.command; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import com.baselet.control.Main; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; public class ChangeElementSetting extends Command { private String key; private Map elementValueMap; private Map oldValue; public ChangeElementSetting(String key, String value, Collection element) { this(key, createSingleValueMap(value, element)); } public ChangeElementSetting(String key, Map elementValueMap) { this.key = key; this.elementValueMap = elementValueMap; } @Override public void execute(DiagramHandler handler) { super.execute(handler); oldValue = new HashMap(); for (Entry entry : elementValueMap.entrySet()) { GridElement e = entry.getKey(); oldValue.put(e, e.getSetting(key)); e.setProperty(key, entry.getValue()); if (handler.getDrawPanel().getSelector().isSelected(e)) { Main.getHandlerForElement(e).getDrawPanel().getSelector().updateSelectorInformation(); // update the property panel to display changed attributes } } handler.getDrawPanel().repaint(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); for (Entry entry : oldValue.entrySet()) { entry.getKey().setProperty(key, entry.getValue()); } handler.getDrawPanel().repaint(); } private static Map createSingleValueMap(String value, Collection elements) { Map singleValueMap = new HashMap(1); for (GridElement e : elements) { singleValueMap.put(e, value); } return singleValueMap; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Search.java0000644000175000017500000000335412533641120024045 0ustar benbenpackage com.baselet.gui.command; import java.awt.Color; import java.awt.Point; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.diagram.SelectorOld; import com.baselet.element.interfaces.GridElement; public class Search extends Command { static Color _failed = new Color(227, 127, 127); static Color _success = new Color(148, 172, 251); private String regex; private Pattern pattern; public Search(String regex) { this.regex = ".*(" + regex.toLowerCase() + ").*"; } @Override public void execute(DiagramHandler handler) { super.execute(handler); SelectorOld s = handler.getDrawPanel().getSelector(); s.deselectAll(); DrawPanel d = handler.getDrawPanel(); pattern = Pattern.compile(regex); Matcher m; for (GridElement e : d.getGridElements()) { m = pattern.matcher(e.getPanelAttributes().toLowerCase()); if (m.find()) { s.select(e); } } if (s.getSelectedElements().size() == 0) { return; } Rectangle panelview = Converter.convert(d.getVisibleRect()); Point p = null; for (GridElement e : s.getSelectedElements()) { if (panelview.contains(e.getRectangle())) { p = new Point(0, 0); break; } else if (p == null) { p = new Point(e.getRectangle().x - panelview.x - 10, e.getRectangle().y - panelview.y - 10); } } if (p != null) { d.changeViewPosition(p.x, p.y); } } @Override public void undo(DiagramHandler handler) { super.undo(handler); handler.getDrawPanel().getSelector().deselectAll(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/OldMoveLinePoint.java0000644000175000017500000000345512533641120026031 0ustar benbenpackage com.baselet.gui.command; import com.baselet.control.Main; import com.baselet.diagram.DiagramHandler; import com.baselet.element.old.element.Relation; /** * only for old deprecated relation; new relation handles linepoint movement in the class-code */ @Deprecated public class OldMoveLinePoint extends Command { private final Relation _relation; private final int _linePointId, _diffx, _diffy; public int getLinePointId() { return _linePointId; } public Relation getRelation() { return _relation; } public int getDiffX() { return _diffx * Main.getHandlerForElement(_relation).getGridSize(); } public int getDiffY() { return _diffy * Main.getHandlerForElement(_relation).getGridSize(); } public OldMoveLinePoint(Relation rel, int i, int diffx, int diffy) { _relation = rel; _linePointId = i; _diffx = diffx / Main.getHandlerForElement(rel).getGridSize(); _diffy = diffy / Main.getHandlerForElement(rel).getGridSize(); } @Override public void execute(DiagramHandler handler) { super.execute(handler); _relation.moveLinePoint(_linePointId, getDiffX(), getDiffY()); } @Override public void undo(DiagramHandler handler) { super.undo(handler); _relation.moveLinePoint(_linePointId, -getDiffX(), -getDiffY()); } @Override public boolean isMergeableTo(Command c) { if (!(c instanceof OldMoveLinePoint)) { return false; } OldMoveLinePoint mlp = (OldMoveLinePoint) c; if (getRelation() != mlp.getRelation()) { return false; } if (getLinePointId() != mlp.getLinePointId()) { return false; } return true; } @Override public Command mergeTo(Command c) { OldMoveLinePoint tmp = (OldMoveLinePoint) c; OldMoveLinePoint ret = new OldMoveLinePoint(getRelation(), getLinePointId(), getDiffX() + tmp.getDiffX(), getDiffY() + tmp.getDiffY()); return ret; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Cut.java0000644000175000017500000000365212533641120023374 0ustar benbenpackage com.baselet.gui.command; import java.awt.Point; import java.util.Vector; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; public class Cut extends Command { private Vector entities; private Point origin; public Cut() { } @Override public void execute(DiagramHandler handler) { super.execute(handler); if (entities == null) { entities = new Vector(); entities.addAll(handler.getDrawPanel().getSelector().getSelectedElements()); } if (entities.isEmpty()) { return; } // AB: clipboard copy scales the entities to 100%, so we don't have to do it manually ClipBoard.getInstance().copyAndZoomToDefaultLevel(entities, handler); new RemoveElement(entities, false).execute(handler); // AB: copy origin and zoom it to 100% origin = handler.getDrawPanel().getOriginAtDefaultZoom(); handler.getDrawPanel().updatePanelAndScrollbars(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); // We must zoom to the defaultGridsize before execution int oldZoom = handler.getGridSize(); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); int offsetX = origin.x - handler.getDrawPanel().getOriginAtDefaultZoom().x; int offsetY = origin.y - handler.getDrawPanel().getOriginAtDefaultZoom().y; for (GridElement e : entities) { new AddElement(e, handler.realignToGrid(true, e.getRectangle().x + offsetX), handler.realignToGrid(true, e.getRectangle().y + offsetY), false).execute(handler); } handler.getDrawPanel().repaint(); // And zoom back to the oldGridsize after execution handler.setGridAndZoom(oldZoom, false); handler.getDrawPanel().getSelector().select(entities); // undo selects the cutted entities handler.getDrawPanel().updatePanelAndScrollbars(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/OldResize.java0000644000175000017500000001330012533641120024530 0ustar benbenpackage com.baselet.gui.command; import java.util.Collection; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.geom.Point; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.SharedConfig; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.element.Relation; import com.baselet.element.sticking.StickingPolygon; /** * resizing has been merged with Move command and only remains for old grid elements which will not be migrated but removed from the code after some time */ @Deprecated public class OldResize extends Command { private int current_id = 0; private int id; private final int diffx, diffy, diffw, diffh; private Vector linepoints; private final Vector move_commands; private final GridElement entity; private int getDiffx() { return diffx * Main.getHandlerForElement(entity).getGridSize(); } private int getDiffy() { return diffy * Main.getHandlerForElement(entity).getGridSize(); } private int getDiffw() { return diffw * Main.getHandlerForElement(entity).getGridSize(); } private int getDiffh() { return diffh * Main.getHandlerForElement(entity).getGridSize(); } public OldResize(GridElement entity, int diffx, int diffy, int diffw, int diffh) { this(entity, diffx, diffy, diffw, diffh, null); } // resize for merge private OldResize(GridElement entity, int id, int diffx, int diffy, int diffw, int diffh, Vector move_commands, Vector move_commands2) { this.entity = entity; this.id = id; this.move_commands = move_commands; this.move_commands.addAll(move_commands2); this.diffx = diffx / Main.getHandlerForElement(entity).getGridSize(); this.diffy = diffy / Main.getHandlerForElement(entity).getGridSize(); this.diffw = diffw / Main.getHandlerForElement(entity).getGridSize(); this.diffh = diffh / Main.getHandlerForElement(entity).getGridSize(); } public OldResize(GridElement entity, int diffx, int diffy, int diffw, int diffh, OldResize first) { this.entity = entity; move_commands = new Vector(); this.diffx = diffx / Main.getHandlerForElement(entity).getGridSize(); this.diffy = diffy / Main.getHandlerForElement(entity).getGridSize(); this.diffw = (diffw - diffx) / Main.getHandlerForElement(entity).getGridSize(); this.diffh = (diffh - diffy) / Main.getHandlerForElement(entity).getGridSize(); Rectangle entityRect = this.entity.getRectangle(); StickingPolygon from = this.entity.generateStickingBorder(entityRect); // AB: FIXED: Use this.diffw/this.diffh instead of diffw/diffh as calculation base Rectangle newRect = new Rectangle(entityRect.x + diffx, entityRect.y + diffy, entityRect.width + getDiffw(), entityRect.height + getDiffh()); StickingPolygon to = this.entity.generateStickingBorder(newRect); if (first != null) { id = first.id; linepoints = first.linepoints; } else { id = current_id; current_id++; linepoints = getStickingRelationLinePoints(Main.getHandlerForElement(this.entity), from); } PointDouble diff; Point p; Relation r; for (OldRelationLinePoint lp : linepoints) { r = lp.getRelation(); p = r.getLinePoints().get(lp.getLinePointId()); diff = from.getLine(lp.getStickingLineId()).diffToLine(to.getLine(lp.getStickingLineId()), p.x + r.getRectangle().x, p.y + r.getRectangle().y); DiagramHandler handler = Main.getHandlerForElement(entity); move_commands.add(new OldMoveLinePoint(lp.getRelation(), lp.getLinePointId(), handler.realignToGrid(diff.x), handler.realignToGrid(diff.y))); } } @Override public void execute(DiagramHandler handler) { super.execute(handler); entity.setLocationDifference(getDiffx(), getDiffy()); entity.setSize(entity.getRectangle().width + getDiffw(), entity.getRectangle().height + getDiffh()); if (SharedConfig.getInstance().isStickingEnabled()) { for (OldMoveLinePoint c : move_commands) { c.execute(handler); } } } @Override public void undo(DiagramHandler handler) { super.undo(handler); entity.setLocationDifference(-getDiffx(), -getDiffy()); entity.setSize(entity.getRectangle().width + -getDiffw(), entity.getRectangle().height + -getDiffh()); for (OldMoveLinePoint c : move_commands) { c.undo(handler); } CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().updatePanelAndScrollbars(); } @Override public boolean isMergeableTo(Command c) { if (!(c instanceof OldResize)) { return false; } OldResize r = (OldResize) c; if (id == r.id) { return true; } return false; } @Override public Command mergeTo(Command c) { OldResize tmp = (OldResize) c; return new OldResize(entity, Math.max(id, tmp.id), getDiffx() + tmp.getDiffx(), getDiffy() + tmp.getDiffy(), getDiffw() + tmp.getDiffw(), getDiffh() + tmp.getDiffh(), move_commands, tmp.move_commands); } public static Vector getStickingRelationLinePoints(DiagramHandler handler, StickingPolygon stickingPolygon) { Vector lpts = new Vector(); Collection rels = handler.getDrawPanel().getOldRelations(); for (Relation r : rels) { PointDouble l1 = r.getAbsoluteCoorStart(); PointDouble l2 = r.getAbsoluteCoorEnd(); int c1 = stickingPolygon.isConnected(l1, handler.getGridSize()); int c2 = stickingPolygon.isConnected(l2, handler.getGridSize()); if (c1 >= 0) { lpts.add(new OldRelationLinePoint(r, 0, c1)); } if (c2 >= 0) { lpts.add(new OldRelationLinePoint(r, r.getLinePoints().size() - 1, c2)); } } return lpts; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Align.java0000644000175000017500000000605512533641120023673 0ustar benbenpackage com.baselet.gui.command; import java.awt.Point; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; public class Align extends Command { private enum Edge { RIGHT, LEFT, TOP, BOTTOM; } private Point origin; private GridElement dominantEntity; private List entities; private Map orgLocations = new HashMap(); private Edge edge; public Align(List entities, GridElement dominantEntity, String edge) { this.dominantEntity = dominantEntity; this.entities = new ArrayList(entities); this.edge = Edge.valueOf(edge.toUpperCase()); } @Override public void execute(DiagramHandler handler) { super.execute(handler); if (entities.size() == 0 || dominantEntity == null) { return; } // We must zoom to the defaultGridsize before execution int oldZoom = handler.getGridSize(); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); // AB: determine fix points first item (the "dominantly selected" item) GridElement entity = dominantEntity; int left = entity.getRectangle().x; int right = left + entity.getRectangle().width; int top = entity.getRectangle().y; int bottom = top + entity.getRectangle().height; DrawPanel p = handler.getDrawPanel(); for (GridElement e : entities) { Rectangle rectangle = e.getRectangle(); int x = rectangle.x; int y = rectangle.y; switch (edge) { case LEFT: x = left; break; case RIGHT: x = right - e.getRectangle().width; break; case TOP: y = top; break; case BOTTOM: y = bottom - e.getRectangle().height; break; } orgLocations.put(e, new Point(rectangle.x, rectangle.y)); e.setLocation(handler.realignToGrid(true, x), handler.realignToGrid(true, y)); } // And zoom back to the oldGridsize after execution handler.setGridAndZoom(oldZoom, false); // AB: copy origin and zoom it to 100% origin = handler.getDrawPanel().getOriginAtDefaultZoom(); p.updatePanelAndScrollbars(); p.repaint(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); // We must zoom to the defaultGridsize before execution int oldZoom = handler.getGridSize(); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); int offsetX = origin.x - handler.getDrawPanel().getOrigin().x; int offsetY = origin.y - handler.getDrawPanel().getOrigin().y; for (GridElement entity : entities) { Point orgLocation = orgLocations.get(entity); entity.setLocation(handler.realignToGrid(true, orgLocation.x + offsetX), handler.realignToGrid(true, orgLocation.y + offsetY)); } // And zoom back to the oldGridsize after execution handler.setGridAndZoom(oldZoom, false); handler.getDrawPanel().updatePanelAndScrollbars(); handler.getDrawPanel().repaint(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Macro.java0000644000175000017500000000360212533641120023675 0ustar benbenpackage com.baselet.gui.command; import java.util.List; import java.util.Vector; import com.baselet.diagram.DiagramHandler; public class Macro extends Command { private final List _commands; public List getCommands() { return _commands; } public Macro(List v) { _commands = v; } @Override public void execute(DiagramHandler handler) { for (int i = 0; i < _commands.size(); i++) { Command c = _commands.get(i); c.execute(handler); } } @Override public void redo(DiagramHandler handler) { for (int i = 0; i < _commands.size(); i++) { Command c = _commands.get(i); c.redo(handler); } } @Override public void undo(DiagramHandler handler) { super.undo(handler); for (int i = 0; i < _commands.size(); i++) { Command c = _commands.get(i); c.undo(handler); } } @Override public boolean isMergeableTo(Command c) { if (!(c instanceof Macro)) { return false; } Macro m = (Macro) c; List v = m.getCommands(); if (getCommands().size() != v.size()) { return false; } for (int i = 0; i < getCommands().size(); i++) { Command c1 = getCommands().get(i); Command c2 = v.get(i); if (!c1.isMergeableTo(c2)) { return false; } } return true; } @Override public Command mergeTo(Command c) { Macro m = (Macro) c; List v = m.getCommands(); List vectorOfCommands = new Vector(); Command ret = new Macro(vectorOfCommands); for (int i = 0; i < getCommands().size(); i++) { Command c1 = getCommands().get(i); Command c2 = v.get(i); Command c3 = c1.mergeTo(c2); vectorOfCommands.add(c3); } return ret; } @Override public boolean isChangingDiagram() { for (Command c : _commands) { if (c.isChangingDiagram()) { return true; } } return false; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/OldRelationLinePoint.java0000644000175000017500000000103612533641120026671 0ustar benbenpackage com.baselet.gui.command; import com.baselet.element.old.element.Relation; public class OldRelationLinePoint { private Relation _relation; private int _linePointId; private int stickingLineId; public Relation getRelation() { return _relation; } public int getLinePointId() { return _linePointId; } public int getStickingLineId() { return stickingLineId; } public OldRelationLinePoint(Relation r, int lp, int stick) { _relation = r; _linePointId = lp; stickingLineId = stick; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/ChangePanelAttributes.java0000644000175000017500000000473212533641120027055 0ustar benbenpackage com.baselet.gui.command; import com.baselet.control.Main; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.gui.pane.OwnSyntaxPane; public class ChangePanelAttributes extends Command { private GridElement _entity; public GridElement getEntity() { return _entity; } private String _newState; private String _oldState; private int _oldCaret; private int _newCaret; public String getNewState() { return _newState; } public String getOldState() { return _oldState; } public int getOldCaret() { return _oldCaret; } public int getNewCaret() { return _newCaret; } public ChangePanelAttributes(GridElement e, String oldState, String newState, int oldCaret, int newCaret) { _entity = e; _newState = newState; _oldState = oldState; _newCaret = newCaret; _oldCaret = oldCaret; } @Override public void execute(DiagramHandler handler) { super.execute(handler); _entity.setPanelAttributes(_newState); _entity.repaint(); GridElement gridElement = Main.getInstance().getEditedGridElement(); if (gridElement != null && gridElement.equals(_entity)) { OwnSyntaxPane pane = CurrentGui.getInstance().getGui().getPropertyPane(); pane.switchToElement(gridElement); if (pane.getText().length() >= _newCaret) { pane.getTextComponent().setCaretPosition(_newCaret); } } } @Override public void undo(DiagramHandler handler) { // AB: Do not call super.undo() which would deselect the entity // super.undo(handler); _entity.setPanelAttributes(_oldState); _entity.repaint(); GridElement gridElement = Main.getInstance().getEditedGridElement(); if (gridElement != null && gridElement.equals(_entity)) { OwnSyntaxPane pane = CurrentGui.getInstance().getGui().getPropertyPane(); pane.switchToElement(gridElement); if (pane.getText().length() >= _oldCaret) { pane.getTextComponent().setCaretPosition(_oldCaret); } } } @Override public boolean isMergeableTo(Command c) { // method is not mergeable (to allow undo of property changes) return false; } @Override public Command mergeTo(Command c) { ChangePanelAttributes tmp = (ChangePanelAttributes) c; ChangePanelAttributes ret = new ChangePanelAttributes(getEntity(), tmp.getOldState(), getNewState(), tmp.getOldCaret(), getNewCaret()); return ret; } @Override public String toString() { return "Changestate from " + getOldState() + " to " + getNewState(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/AddElement.java0000644000175000017500000000631312533641120024640 0ustar benbenpackage com.baselet.gui.command; import java.awt.Point; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; public class AddElement extends Command { private static final Logger log = Logger.getLogger(AddElement.class); // AB: checked false after first execution private boolean firstCall = true; private Point origin; private GridElement _entity; private int _x; private int _y; private boolean _zoom; private int getX() { // AB: use default grid size since we zoom the whole entity on execution if (_zoom) { return _x * Constants.DEFAULTGRIDSIZE;// _entity.getHandler().getGridSize(); } else { return _x; } } private int getY() { // AB: use default grid size since we zoom the whole entity on execution if (_zoom) { return _y * Constants.DEFAULTGRIDSIZE;// _entity.getHandler().getGridSize(); } else { return _y; } } public AddElement(GridElement e, int x, int y) { this(e, x, y, true); } public AddElement(GridElement e, int x, int y, boolean zoom) { _entity = e; _zoom = zoom; if (_zoom) { _x = x / Main.getHandlerForElement(e).getGridSize(); _y = y / Main.getHandlerForElement(e).getGridSize(); DiagramHandler.zoomEntity(Main.getHandlerForElement(e).getGridSize(), Constants.DEFAULTGRIDSIZE, e); } else { _x = x; _y = y; } } private void addentity(GridElement e, DrawPanel panel, int x, int y) { panel.getHandler().setHandlerAndInitListeners(e); panel.addElement(e); e.setLocation(x, y); } @Override public void execute(DiagramHandler handler) { super.execute(handler); // AB: set origin for the first execution; // NOTE this cannot be done in constructor since we cannot rely that the handler in the constructor is the same as here if (origin == null) { origin = handler.getDrawPanel().getOriginAtDefaultZoom(); } // AB: calculate offset so that we add it on the same position on redo // NOTE the first time the command is executed, the offset is 0 int offsetX = origin.x - handler.getDrawPanel().getOriginAtDefaultZoom().x; int offsetY = origin.y - handler.getDrawPanel().getOriginAtDefaultZoom().y; log.debug("Add Entity at " + getX() + "/" + getY()); addentity(_entity, handler.getDrawPanel(), getX() + offsetX, getY() + offsetY); if (_zoom) { DiagramHandler.zoomEntity(Constants.DEFAULTGRIDSIZE, handler.getGridSize(), _entity); } handler.getDrawPanel().getSelector().selectOnly(_entity); // AB: do this because updatePanelAndScrollbars messes up frequent calls of AddEntity in a loop if (!firstCall) { handler.getDrawPanel().updatePanelAndScrollbars(); } firstCall = false; } @Override public void undo(DiagramHandler handler) { super.undo(handler); if (_zoom) { DiagramHandler.zoomEntity(handler.getGridSize(), Constants.DEFAULTGRIDSIZE, _entity); } handler.getDrawPanel().removeElement(_entity); new RemoveElement(_entity, false).execute(handler); // zoom must be false otherwise groups don't work correctly handler.getDrawPanel().repaint(); handler.getDrawPanel().updatePanelAndScrollbars(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/RemoveElement.java0000644000175000017500000000413112533641120025401 0ustar benbenpackage com.baselet.gui.command; import java.awt.Point; import java.util.ArrayList; import java.util.List; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.interfaces.GridElement; public class RemoveElement extends Command { private List _entities; private Point origin; private boolean _zoom; public RemoveElement(GridElement e) { this(e, true); } public RemoveElement(GridElement e, boolean zoom) { _entities = new ArrayList(); _entities.add(e); _zoom = zoom; } public RemoveElement(List v) { this(v, true); } public RemoveElement(List v, boolean zoom) { _entities = new ArrayList(); _entities.addAll(v); _zoom = zoom; } @Override public void execute(DiagramHandler handler) { super.execute(handler); if (_entities.size() == 0) { return; } DrawPanel p = handler.getDrawPanel(); for (GridElement e : _entities) { handler.getDrawPanel().removeElement(e); } origin = handler.getDrawPanel().getOriginAtDefaultZoom(); if (_zoom) { DiagramHandler.zoomEntities(handler.getGridSize(), Constants.DEFAULTGRIDSIZE, _entities); } p.updatePanelAndScrollbars(); p.repaint(); p.getSelector().deselectAll(); } @Override public void undo(DiagramHandler handler) { super.undo(handler); if (_zoom) { DiagramHandler.zoomEntities(Constants.DEFAULTGRIDSIZE, handler.getGridSize(), _entities); } int offsetX = origin.x - handler.getDrawPanel().getOriginAtDefaultZoom().x; int offsetY = origin.y - handler.getDrawPanel().getOriginAtDefaultZoom().y; offsetX = offsetX * handler.getGridSize() / Constants.DEFAULTGRIDSIZE; offsetY = offsetY * handler.getGridSize() / Constants.DEFAULTGRIDSIZE; for (GridElement e : _entities) { new AddElement(e, handler.realignToGrid(e.getRectangle().x + offsetX), handler.realignToGrid(e.getRectangle().y + offsetY), _zoom).execute(handler); } handler.getDrawPanel().updatePanelAndScrollbars(); handler.getDrawPanel().repaint(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Move.java0000644000175000017500000001215312533641120023543 0ustar benbenpackage com.baselet.gui.command; import java.util.Collection; import org.apache.log4j.Logger; import com.baselet.control.Main; import com.baselet.control.basics.geom.Point; import com.baselet.control.enums.Direction; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.element.sticking.StickableMap; public class Move extends Command { private static final Logger log = Logger.getLogger(Move.class); private final GridElement entity; private final int x, y; private final double mouseX; private final double mouseY; private final boolean isShiftKeyDown; private final boolean firstDrag; private final boolean useSetLocation; private final StickableMap stickables; private final Collection resizeDirection; public GridElement getEntity() { return entity; } private int getX() { int zoomedX = x * gridSize(); log.debug("Zoomed x: " + zoomedX); return zoomedX; } private int gridSize() { return Main.getHandlerForElement(entity).getGridSize(); } private int getY() { int zoomedY = y * gridSize(); log.debug("Zoomed y: " + zoomedY); return zoomedY; } public StickableMap getStickables() { return stickables; } public boolean isShiftKeyDown() { return isShiftKeyDown; } private Point getMousePosBeforeDrag() { Double zoomedX = mouseX * gridSize(); Double zoomedY = mouseY * gridSize(); Point p = new Point((int) Math.round(zoomedX), (int) Math.round(zoomedY)); log.debug("Zoomed point: " + p); return p; } public Move(Collection resizeDirection, boolean absoluteMousePos, GridElement e, int x, int y, Point mousePosBeforeDrag, boolean isShiftKeyDown, boolean firstDrag, boolean useSetLocation, StickableMap stickingStickables) { entity = e; int gridSize = Main.getHandlerForElement(e).getGridSize(); this.x = x / gridSize; this.y = y / gridSize; mouseX = calcRelativePos(absoluteMousePos, mousePosBeforeDrag.getX(), entity.getRectangle().getX(), gridSize); mouseY = calcRelativePos(absoluteMousePos, mousePosBeforeDrag.getY(), entity.getRectangle().getY(), gridSize); this.isShiftKeyDown = isShiftKeyDown; this.firstDrag = firstDrag; this.useSetLocation = useSetLocation; stickables = stickingStickables; this.resizeDirection = resizeDirection; } public Move(Collection resizeDirection, GridElement e, int x, int y, Point mousePosBeforeDrag, boolean isShiftKeyDown, boolean firstDrag, boolean useSetLocation, StickableMap stickingStickables) { this(resizeDirection, true, e, x, y, mousePosBeforeDrag, isShiftKeyDown, firstDrag, useSetLocation, stickingStickables); } /** * Calculates the mouse position * @param absoluteMousePos if true then the element location must be subtracted to get a relative position instead of an absolute, otherwise it's already relative * @param mousePos the absolute mouse position * @param entityLocation the location of the entity * @param gridSize the result is divided by the gridsize because it can be (re)executed on different gridSizes (eg do on 100% zoom, change to 50% zoom and undo/redo) * @return the mouse position relative to the element, independend from gridSize */ private double calcRelativePos(boolean absoluteMousePos, int mousePos, int entityLocation, double gridSize) { double xCalcBase = mousePos * 1.0; if (absoluteMousePos) { xCalcBase -= entityLocation; } return xCalcBase / gridSize; } @Override public void execute(DiagramHandler handler) { super.execute(handler); if (useSetLocation) { entity.setRectangleDifference(getX(), getY(), 0, 0, firstDrag, stickables, true); } else { entity.drag(resizeDirection, getX(), getY(), getMousePosBeforeDrag(), isShiftKeyDown, firstDrag, stickables, true); } } @Override public void undo(DiagramHandler handler) { super.undo(handler); entity.undoDrag(); entity.updateModelFromText(); CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().updatePanelAndScrollbars(); } @Override public void redo(DiagramHandler handler) { entity.redoDrag(); entity.updateModelFromText(); CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().updatePanelAndScrollbars(); } @Override public boolean isMergeableTo(Command c) { if (!(c instanceof Move)) { return false; } Move m = (Move) c; boolean stickablesEquals = stickables.equalsMap(m.stickables); boolean shiftEquals = isShiftKeyDown == m.isShiftKeyDown; boolean notBothFirstDrag = !(firstDrag && m.firstDrag); return entity == m.entity && useSetLocation == m.useSetLocation && stickablesEquals && shiftEquals && notBothFirstDrag; } @Override public Command mergeTo(Command c) { Move m = (Move) c; Point mousePosBeforeDrag = firstDrag ? getMousePosBeforeDrag() : m.getMousePosBeforeDrag(); // Important: absoluteMousePos=false, because the mousePos is already relative from the first constructor call! Move ret = new Move(m.resizeDirection, false, entity, getX() + m.getX(), getY() + m.getY(), mousePosBeforeDrag, isShiftKeyDown, firstDrag || m.firstDrag, useSetLocation, stickables); entity.mergeUndoDrag(); return ret; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/ClipBoard.java0000644000175000017500000000400112533641120024465 0ustar benbenpackage com.baselet.gui.command; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.util.ArrayList; import java.util.List; import com.baselet.control.constants.Constants; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.io.OutputHandler; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; /** Copies and Pastes images to the system clipboard. Requires Java 2, v1.4. */ public class ClipBoard implements Transferable { private final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); private List entities; private static ClipBoard _instance = new ClipBoard(); public static ClipBoard getInstance() { return _instance; } public void copyAndZoomToDefaultLevel(List entities, DiagramHandler handler) { if (entities.isEmpty()) { return; } this.entities = new ArrayList(entities); // clipboard zooms entities to 100% (to make them zoom-independent) DiagramHandler.zoomEntities(handler.getGridSize(), Constants.DEFAULTGRIDSIZE, this.entities); CurrentGui.getInstance().getGui().enablePasteMenuEntry(); if (clipboard != null) { // Issue 230: copy after zooming the entities clipboard.setContents(this, null); } } public List paste() { return entities; } @Override public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] { DataFlavor.imageFlavor }; } @Override public boolean isDataFlavorSupported(DataFlavor flavor) { return DataFlavor.imageFlavor.equals(flavor); } @Override public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { if (!isDataFlavorSupported(flavor)) { throw new UnsupportedFlavorException(flavor); } return OutputHandler.createImageForGridElements(entities); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/CustomCodePropertyChanged.java0000644000175000017500000000574712533641120027734 0ustar benbenpackage com.baselet.gui.command; import com.baselet.control.Main; import com.baselet.diagram.CustomPreviewHandler; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.SelectorOld; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.CurrentGui; import com.baselet.gui.pane.OwnSyntaxPane; public class CustomCodePropertyChanged extends Command { // private GridElement _entity; private String _newState; private String _oldState; private int _oldCaret; private int _newCaret; public String getNewState() { return _newState; } public String getOldState() { return _oldState; } public int getOldCaret() { return _oldCaret; } public int getNewCaret() { return _newCaret; } public CustomCodePropertyChanged(String oldState, String newState, int oldCaret, int newCaret) { _newState = newState; _oldState = oldState; _newCaret = newCaret; _oldCaret = oldCaret; } @Override public void execute(DiagramHandler handler) { super.execute(handler); GridElement gridElement = Main.getInstance().getEditedGridElement(); // select grid element if nothing is selected if (gridElement == null) { SelectorOld selector = CurrentGui.getInstance().getGui().getCurrentCustomHandler().getPreviewHandler().getDrawPanel().getSelector(); selector.selectAll(); if (selector.getSelectedElements().size() >= 1) { gridElement = selector.getSelectedElements().get(0); } } if (gridElement != null && Main.getHandlerForElement(gridElement) instanceof CustomPreviewHandler) { gridElement.setPanelAttributes(_newState); OwnSyntaxPane pane = CurrentGui.getInstance().getGui().getPropertyPane(); pane.switchToElement(gridElement); if (pane.getText().length() >= _newCaret) { pane.getTextComponent().setCaretPosition(_newCaret); } gridElement.repaint(); } } @Override public void undo(DiagramHandler handler) { // AB: Do not call super.undo() which would deselect the entity // super.undo(handler); GridElement gridElement = Main.getInstance().getEditedGridElement(); // select grid element if (gridElement == null) { SelectorOld selector = CurrentGui.getInstance().getGui().getCurrentCustomHandler().getPreviewHandler().getDrawPanel().getSelector(); selector.selectAll(); if (selector.getSelectedElements().size() >= 1) { gridElement = selector.getSelectedElements().get(0); } } if (gridElement != null && Main.getHandlerForElement(gridElement) instanceof CustomPreviewHandler) { gridElement.setPanelAttributes(_oldState); OwnSyntaxPane pane = CurrentGui.getInstance().getGui().getPropertyPane(); pane.switchToElement(gridElement); if (pane.getText().length() >= _oldCaret) { pane.getTextComponent().setCaretPosition(_oldCaret); } gridElement.repaint(); } } @Override public String toString() { return "Changestate from " + getOldState() + " to " + getNewState(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/Command.java0000644000175000017500000000133512533641120024213 0ustar benbenpackage com.baselet.gui.command; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.SelectorOld; public abstract class Command { public void execute(@SuppressWarnings("unused") DiagramHandler handler) { } public void undo(DiagramHandler handler) { if (handler != null) { SelectorOld selector = handler.getDrawPanel().getSelector(); if (selector != null) { selector.deselectAll(); } } } public boolean isMergeableTo(@SuppressWarnings("unused") Command c) { return false; } public Command mergeTo(@SuppressWarnings("unused") Command c) { return null; } public void redo(DiagramHandler handler) { execute(handler); } public boolean isChangingDiagram() { return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/command/MoveEnd.java0000644000175000017500000000113712533641120024172 0ustar benbenpackage com.baselet.gui.command; import com.baselet.diagram.DiagramHandler; import com.baselet.element.interfaces.GridElement; public class MoveEnd extends Command { private GridElement e; public MoveEnd(GridElement e) { this.e = e; } @Override public void execute(DiagramHandler handler) { super.execute(handler); e.dragEnd(); } @Override public boolean isMergeableTo(Command c) { if (c instanceof Macro) { return true; } return false; } @Override public Command mergeTo(Command c) { ((Macro) c).getCommands().add(this); return c; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/CurrentGui.java0000644000175000017500000000051112533641120023301 0ustar benbenpackage com.baselet.gui; public class CurrentGui { private final static CurrentGui instance = new CurrentGui(); public static CurrentGui getInstance() { return instance; } private BaseGUI gui; public void setGui(BaseGUI gui) { this.gui = gui; } public BaseGUI getGui() { return gui; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/menu/0000755000175000017500000000000012533641120021316 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/menu/GenerateOptionPanel.java0000644000175000017500000001377212533641120026076 0ustar benbenpackage com.baselet.gui.menu; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Enumeration; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JRadioButton; import com.baselet.control.config.ConfigClassGen; import com.baselet.control.enums.generator.FieldOptions; import com.baselet.control.enums.generator.MethodOptions; import com.baselet.control.enums.generator.SignatureOptions; import com.baselet.control.enums.generator.SortOptions; @SuppressWarnings("serial") public class GenerateOptionPanel extends JDialog { private static GenerateOptionPanel optionpanel; private JCheckBox packageInfo; private ButtonGroup fields; private ButtonGroup methods; private ButtonGroup signatures; private ButtonGroup sortings; private static final String okButton = "Ok"; private static final String cancelButton = "Cancel"; private GenerateOptionPanel() { Container content = getContentPane(); content.add(createOptionPanel(), BorderLayout.CENTER); content.add(createButtonPanel(), BorderLayout.SOUTH); setTitle("Import Details"); pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation(screenSize.width / 2 - getWidth() / 2, screenSize.height / 2 - getWidth() / 2); } private JPanel createOptionPanel() { JPanel optionPanel = new JPanel(); optionPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); packageInfo = new JCheckBox("Show package"); packageInfo.setSelected(true); optionPanel.add(packageInfo, layout(c, 0, 0)); fields = createButtonGroup(FieldOptions.values()); optionPanel.add(createSubPanel("Show fields", fields), layout(c, 0, 1)); methods = createButtonGroup(MethodOptions.values()); optionPanel.add(createSubPanel("Show methods", methods), layout(c, 1, 1)); signatures = createButtonGroup(SignatureOptions.values()); optionPanel.add(createSubPanel("Show signatures", signatures), layout(c, 0, 2)); sortings = createButtonGroup(SortOptions.values()); optionPanel.add(createSubPanel("Sorting", sortings), layout(c, 1, 2)); optionPanel.validate(); return optionPanel; } private > ButtonGroup createButtonGroup(E[] values) { ButtonGroup group = new ButtonGroup(); for (E value : values) { JRadioButton button = new JRadioButton(value.toString()); button.setActionCommand(value.toString()); group.add(button); } return group; } private GridBagConstraints layout(GridBagConstraints c, int gridx, int gridy) { c.fill = GridBagConstraints.HORIZONTAL; c.gridx = gridx; c.gridy = gridy; return c; } private JPanel createSubPanel(String title, ButtonGroup group) { Enumeration e = group.getElements(); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(0, 1)); panel.setBorder(BorderFactory.createTitledBorder(title)); while (e.hasMoreElements()) { panel.add(e.nextElement()); } return panel; } private JPanel createButtonPanel() { CancelOkListener listener = new CancelOkListener(); JButton button_ok = new JButton(okButton); button_ok.setActionCommand(okButton); button_ok.addActionListener(listener); JButton button_cancel = new JButton(cancelButton); button_cancel.setActionCommand(cancelButton); button_cancel.addActionListener(listener); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); buttonPanel.add(Box.createHorizontalGlue()); buttonPanel.add(button_cancel); buttonPanel.add(Box.createRigidArea(new Dimension(20, 0))); buttonPanel.add(button_ok); buttonPanel.add(Box.createHorizontalGlue()); buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT); return buttonPanel; } public static GenerateOptionPanel getInstance() { if (optionpanel == null) { optionpanel = new GenerateOptionPanel(); } return optionpanel; } private class CancelOkListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { optionpanel.setVisible(false); if (e.getActionCommand().equals(okButton)) { ConfigClassGen genCfg = ConfigClassGen.getInstance(); genCfg.setGenerateClassPackage(packageInfo.isSelected()); genCfg.setGenerateClassFields(FieldOptions.getEnum(fields.getSelection().getActionCommand().toString())); genCfg.setGenerateClassMethods(MethodOptions.getEnum(methods.getSelection().getActionCommand().toString())); genCfg.setGenerateClassSignatures(SignatureOptions.getEnum(signatures.getSelection().getActionCommand().toString())); genCfg.setGenerateClassSortings(SortOptions.getEnum(sortings.getSelection().getActionCommand().toString())); } } } public void showPanel() { ConfigClassGen genCfg = ConfigClassGen.getInstance(); packageInfo.setSelected(genCfg.isGenerateClassPackage()); setSelectedRadioButton(fields, genCfg.getGenerateClassFields()); setSelectedRadioButton(methods, genCfg.getGenerateClassMethods()); setSelectedRadioButton(signatures, genCfg.getGenerateClassSignatures()); setSelectedRadioButton(sortings, genCfg.getGenerateClassSortings()); setVisible(true); toFront(); } private > void setSelectedRadioButton(ButtonGroup group, E value) { Enumeration buttons = group.getElements(); while (buttons.hasMoreElements()) { AbstractButton button = buttons.nextElement(); if (button.getActionCommand().equals(value.toString())) { button.setSelected(true); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/menu/AboutDialog.java0000644000175000017500000000237512533641120024362 0ustar benbenpackage com.baselet.gui.menu; import java.awt.Color; import java.io.IOException; import java.net.URL; import javax.swing.JDialog; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.border.LineBorder; import org.apache.log4j.Logger; import com.baselet.control.enums.Program; import com.baselet.control.util.Path; import com.baselet.gui.listener.HyperLinkActiveListener; public class AboutDialog { private static final Logger log = Logger.getLogger(AboutDialog.class); public static void show() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { final JEditorPane edit = new JEditorPane(); edit.setBorder(new LineBorder(Color.GRAY, 1, true)); edit.setPage(new URL("file:///" + Path.homeProgram() + "html/about.html")); edit.addHyperlinkListener(new HyperLinkActiveListener()); edit.setEditable(false); edit.setSelectionColor(Color.WHITE); JDialog instance = new JOptionPane(edit, JOptionPane.PLAIN_MESSAGE).createDialog("About " + Program.getInstance().getProgramName()); instance.setVisible(true); } catch (IOException e) { log.error(null, e); } } }); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/menu/MenuFactorySwing.java0000644000175000017500000002711612533641120025434 0ustar benbenpackage com.baselet.gui.menu; import static com.baselet.control.constants.MenuConstants.ABOUT_PROGRAM; import static com.baselet.control.constants.MenuConstants.ALIGN; import static com.baselet.control.constants.MenuConstants.COPY; import static com.baselet.control.constants.MenuConstants.CUSTOM_ELEMENTS_TUTORIAL; import static com.baselet.control.constants.MenuConstants.CUT; import static com.baselet.control.constants.MenuConstants.DELETE; import static com.baselet.control.constants.MenuConstants.EDIT_CURRENT_PALETTE; import static com.baselet.control.constants.MenuConstants.EDIT_SELECTED; import static com.baselet.control.constants.MenuConstants.EXIT; import static com.baselet.control.constants.MenuConstants.EXPORT_AS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS_OPTIONS; import static com.baselet.control.constants.MenuConstants.GROUP; import static com.baselet.control.constants.MenuConstants.LAYER; import static com.baselet.control.constants.MenuConstants.LAYER_DOWN; import static com.baselet.control.constants.MenuConstants.LAYER_UP; import static com.baselet.control.constants.MenuConstants.MAIL_TO; import static com.baselet.control.constants.MenuConstants.NEW; import static com.baselet.control.constants.MenuConstants.NEW_CE; import static com.baselet.control.constants.MenuConstants.NEW_FROM_TEMPLATE; import static com.baselet.control.constants.MenuConstants.ONLINE_HELP; import static com.baselet.control.constants.MenuConstants.ONLINE_SAMPLE_DIAGRAMS; import static com.baselet.control.constants.MenuConstants.OPEN; import static com.baselet.control.constants.MenuConstants.OPTIONS; import static com.baselet.control.constants.MenuConstants.PASTE; import static com.baselet.control.constants.MenuConstants.PRINT; import static com.baselet.control.constants.MenuConstants.PROGRAM_HOMEPAGE; import static com.baselet.control.constants.MenuConstants.RATE_PROGRAM; import static com.baselet.control.constants.MenuConstants.RECENT_FILES; import static com.baselet.control.constants.MenuConstants.REDO; import static com.baselet.control.constants.MenuConstants.SAVE; import static com.baselet.control.constants.MenuConstants.SAVE_AS; import static com.baselet.control.constants.MenuConstants.SELECT_ALL; import static com.baselet.control.constants.MenuConstants.SET_BACKGROUND_COLOR; import static com.baselet.control.constants.MenuConstants.SET_FOREGROUND_COLOR; import static com.baselet.control.constants.MenuConstants.UNDO; import static com.baselet.control.constants.MenuConstants.UNGROUP; import static com.baselet.control.constants.MenuConstants.VIDEO_TUTORIAL; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import com.baselet.control.Main; import com.baselet.control.constants.Constants; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Os; import com.baselet.control.util.RecentlyUsedFilesList; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.gui.helper.PlainColorIcon; public class MenuFactorySwing extends MenuFactory { private static MenuFactorySwing instance = null; public static MenuFactorySwing getInstance() { if (instance == null) { instance = new MenuFactorySwing(); } return instance; } public JMenuItem createNew() { return createJMenuItem(false, NEW, KeyEvent.VK_N, true, null); } public JMenuItem createOpen() { return createJMenuItem(false, OPEN, KeyEvent.VK_O, true, null); } public JMenu createRecentFiles() { final JMenu recentFiles = new JMenu(); recentFiles.setText(RECENT_FILES); recentFiles.addMenuListener(new MenuListener() { @Override public void menuDeselected(MenuEvent e) {} @Override public void menuCanceled(MenuEvent e) {} @Override public void menuSelected(MenuEvent e) { recentFiles.removeAll(); for (String file : RecentlyUsedFilesList.getInstance()) { recentFiles.add(createJMenuItem(false, file, RECENT_FILES, file)); } } }); return recentFiles; } public JMenuItem createGenerate() { return createJMenuItem(false, GENERATE_CLASS, null); } public JMenuItem createGenerateOptions() { return createJMenuItem(false, GENERATE_CLASS_OPTIONS, null); } public JMenuItem createSave() { return createJMenuItem(true, SAVE, KeyEvent.VK_S, true, null); } public JMenuItem createSaveAs() { return createJMenuItem(true, SAVE_AS, null); } public JMenu createExportAs() { final JMenu export = new JMenu(); export.setText(EXPORT_AS); diagramDependendComponents.add(export); for (final String format : Constants.exportFormatList) { export.add(createJMenuItem(true, format.toUpperCase() + "...", EXPORT_AS, format)); } return export; } public JMenuItem createMailTo() { return createJMenuItem(true, MAIL_TO, KeyEvent.VK_M, true, null); } public JMenuItem createEditCurrentPalette() { return createJMenuItem(false, EDIT_CURRENT_PALETTE, null); } public JMenuItem createOptions() { return createJMenuItem(false, OPTIONS, null); } public JMenuItem createPrint() { return createJMenuItem(true, PRINT, KeyEvent.VK_P, true, null); } public JMenuItem createExit() { return createJMenuItem(false, EXIT, null); } public JMenuItem createUndo() { return createJMenuItem(false, UNDO, KeyEvent.VK_Z, true, null); } public JMenuItem createRedo() { return createJMenuItem(false, REDO, KeyEvent.VK_Y, true, null); } public JMenuItem createDelete() { int[] keys = new int[] { KeyEvent.VK_BACK_SPACE, KeyEvent.VK_DELETE }; // backspace AND delete both work for deleting elements if (SystemInfo.OS == Os.MAC) { // MacOS shows the backspace key mapping because it's the only one working - see http://stackoverflow.com/questions/4881262/java-keystroke-for-delete/4881606#4881606 return createJMenuItem(false, DELETE, keys, KeyEvent.VK_BACK_SPACE); } else { return createJMenuItem(false, DELETE, keys, KeyEvent.VK_DELETE); } } public JMenuItem createSelectAll() { return createJMenuItem(false, SELECT_ALL, KeyEvent.VK_A, true, null); } public JMenuItem createGroup() { return createJMenuItem(false, GROUP, KeyEvent.VK_G, true, null); } public JMenuItem createUngroup() { return createJMenuItem(false, UNGROUP, KeyEvent.VK_U, true, null); } public JMenuItem createCut() { return createJMenuItem(false, CUT, KeyEvent.VK_X, true, null); } public JMenuItem createCopy() { return createJMenuItem(false, COPY, KeyEvent.VK_C, true, null); } public JMenuItem createPaste() { return createJMenuItem(false, PASTE, KeyEvent.VK_V, true, null); } public JMenuItem createNewCustomElement() { return createJMenuItem(false, NEW_CE, null); } public JMenu createNewCustomElementFromTemplate() { JMenu menu = new JMenu(NEW_FROM_TEMPLATE); for (String template : Main.getInstance().getTemplateNames()) { menu.add(createJMenuItem(false, template, NEW_FROM_TEMPLATE, template)); } return menu; } public JMenuItem createEditSelected() { return createJMenuItem(false, EDIT_SELECTED, null); } public JMenuItem createCustomElementTutorial() { return createJMenuItem(false, CUSTOM_ELEMENTS_TUTORIAL, null); } public JMenuItem createOnlineHelp() { return createJMenuItem(false, ONLINE_HELP, null); } public JMenuItem createOnlineSampleDiagrams() { return createJMenuItem(false, ONLINE_SAMPLE_DIAGRAMS, null); } public JMenuItem createVideoTutorials() { return createJMenuItem(false, VIDEO_TUTORIAL, null); } public JMenuItem createProgramHomepage() { return createJMenuItem(false, PROGRAM_HOMEPAGE, null); } public JMenuItem createRateProgram() { return createJMenuItem(false, RATE_PROGRAM, null); } public JMenu createSetColor(boolean fg) { String name = fg ? SET_FOREGROUND_COLOR : SET_BACKGROUND_COLOR; JMenu menu = new JMenu(name); menu.add(createJMenuItem(false, "default", name, null)); for (String color : ColorOwn.COLOR_MAP.keySet()) { JMenuItem item = createJMenuItem(false, color, name, color); menu.add(item); item.setIcon(new PlainColorIcon(color)); } return menu; } public JMenuItem createAboutProgram() { return createJMenuItem(false, ABOUT_PROGRAM, null); } public JMenu createAlign() { JMenu alignMenu = new JMenu(ALIGN); for (String direction : new String[] { "Left", "Right", "Top", "Bottom" }) { alignMenu.add(createJMenuItem(false, direction, ALIGN, direction)); } return alignMenu; } public JMenu createLayerUp() { JMenu alignMenu = new JMenu(LAYER); for (String direction : new String[] { LAYER_DOWN, LAYER_UP }) { alignMenu.add(createJMenuItem(false, direction, LAYER, direction)); } return alignMenu; } private JMenuItem createJMenuItem(boolean grayWithoutDiagram, final String name, Object param) { return createJMenuItem(grayWithoutDiagram, name, name, null, null, param); } private JMenuItem createJMenuItem(boolean grayWithoutDiagram, final String name, Integer mnemonic, Boolean meta, Object param) { return createJMenuItem(grayWithoutDiagram, name, name, mnemonic, meta, param); } private JMenuItem createJMenuItem(boolean grayWithoutDiagram, final String menuName, final String actionName, final Object param) { return createJMenuItem(grayWithoutDiagram, menuName, actionName, null, null, param); } private JMenuItem createJMenuItem(boolean grayWithoutDiagram, final String menuName, final String actionName, Integer mnemonic, Boolean meta, final Object param) { JMenuItem menuItem = new JMenuItem(menuName); if (mnemonic != null) { menuItem.setMnemonic(mnemonic); menuItem.setAccelerator(KeyStroke.getKeyStroke(mnemonic, !meta ? 0 : SystemInfo.META_KEY.getMask())); } menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { doAction(actionName, param); } }); if (grayWithoutDiagram) { diagramDependendComponents.add(menuItem); } return menuItem; } /** * Create a JMenuItem with multiple key bindings (only one mnemonic can be set at any time). * @see "http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html" */ private JMenuItem createJMenuItem(boolean grayWithoutDiagram, final String name, int[] keyEvents, int preferredMnemonic) { JMenuItem menuItem = new JMenuItem(name); MultipleKeyBindingsAction action = new MultipleKeyBindingsAction(name, preferredMnemonic); for (int keyEvent : keyEvents) { addKeyBinding(menuItem, keyEvent, name); } menuItem.getActionMap().put(name, action); menuItem.setAction(action); if (grayWithoutDiagram) { diagramDependendComponents.add(menuItem); } return menuItem; } private void addKeyBinding(JMenuItem menuItem, int keyEvent, String actionName) { menuItem.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(keyEvent, 0), actionName); } @SuppressWarnings("serial") private class MultipleKeyBindingsAction extends AbstractAction { public MultipleKeyBindingsAction(String menuName, int preferredMnemonic) { super(menuName); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(preferredMnemonic, 0)); } @Override public void actionPerformed(ActionEvent e) { doAction(getValue(NAME).toString(), null); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/menu/MenuFactory.java0000644000175000017500000002627012533641120024424 0ustar benbenpackage com.baselet.gui.menu; import static com.baselet.control.constants.MenuConstants.ABOUT_PROGRAM; import static com.baselet.control.constants.MenuConstants.ALIGN; import static com.baselet.control.constants.MenuConstants.COPY; import static com.baselet.control.constants.MenuConstants.CUSTOM_ELEMENTS_TUTORIAL; import static com.baselet.control.constants.MenuConstants.CUSTOM_ELEMENTS_TUTORIAL_URL; import static com.baselet.control.constants.MenuConstants.CUT; import static com.baselet.control.constants.MenuConstants.DELETE; import static com.baselet.control.constants.MenuConstants.EDIT_CURRENT_PALETTE; import static com.baselet.control.constants.MenuConstants.EDIT_SELECTED; import static com.baselet.control.constants.MenuConstants.EXIT; import static com.baselet.control.constants.MenuConstants.EXPORT_AS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS; import static com.baselet.control.constants.MenuConstants.GENERATE_CLASS_OPTIONS; import static com.baselet.control.constants.MenuConstants.GROUP; import static com.baselet.control.constants.MenuConstants.LAYER; import static com.baselet.control.constants.MenuConstants.LAYER_DOWN; import static com.baselet.control.constants.MenuConstants.MAIL_TO; import static com.baselet.control.constants.MenuConstants.NEW; import static com.baselet.control.constants.MenuConstants.NEW_CE; import static com.baselet.control.constants.MenuConstants.NEW_FROM_TEMPLATE; import static com.baselet.control.constants.MenuConstants.ONLINE_HELP; import static com.baselet.control.constants.MenuConstants.ONLINE_SAMPLE_DIAGRAMS; import static com.baselet.control.constants.MenuConstants.OPEN; import static com.baselet.control.constants.MenuConstants.OPTIONS; import static com.baselet.control.constants.MenuConstants.PASTE; import static com.baselet.control.constants.MenuConstants.PRINT; import static com.baselet.control.constants.MenuConstants.PROGRAM_HOMEPAGE; import static com.baselet.control.constants.MenuConstants.RATE_PROGRAM; import static com.baselet.control.constants.MenuConstants.RECENT_FILES; import static com.baselet.control.constants.MenuConstants.REDO; import static com.baselet.control.constants.MenuConstants.SAVE; import static com.baselet.control.constants.MenuConstants.SAVE_AS; import static com.baselet.control.constants.MenuConstants.SELECT_ALL; import static com.baselet.control.constants.MenuConstants.SET_BACKGROUND_COLOR; import static com.baselet.control.constants.MenuConstants.SET_FOREGROUND_COLOR; import static com.baselet.control.constants.MenuConstants.UNDO; import static com.baselet.control.constants.MenuConstants.UNGROUP; import static com.baselet.control.constants.MenuConstants.VIDEO_TUTORIAL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JComponent; import javax.swing.SwingUtilities; import com.baselet.control.Main; import com.baselet.control.constants.FacetConstants; import com.baselet.control.enums.Program; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.diagram.SelectorOld; import com.baselet.diagram.io.ClassChooser; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.facet.common.LayerFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElement; import com.baselet.generator.ClassDiagramConverter; import com.baselet.gui.BaseGUI; import com.baselet.gui.BrowserLauncher; import com.baselet.gui.CurrentGui; import com.baselet.gui.OptionPanel; import com.baselet.gui.command.Align; import com.baselet.gui.command.ChangeElementSetting; import com.baselet.gui.command.Copy; import com.baselet.gui.command.Cut; import com.baselet.gui.command.Paste; import com.baselet.gui.command.RemoveElement; public class MenuFactory { public void doAction(final String menuItem, final Object param) { // AB: Hopefully this will resolve threading issues and work for eclipse AND standalone SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Main main = Main.getInstance(); BaseGUI gui = CurrentGui.getInstance().getGui(); DiagramHandler diagramHandler = gui.getCurrentDiagram().getHandler(); DiagramHandler actualHandler = CurrentDiagram.getInstance().getDiagramHandler(); SelectorOld actualSelector = actualHandler == null ? null : actualHandler.getDrawPanel().getSelector(); if (menuItem.equals(NEW)) { main.doNew(); } else if (menuItem.equals(OPEN)) { main.doOpenFromFileChooser(); } else if (menuItem.equals(RECENT_FILES)) { main.doOpen((String) param); } else if (menuItem.equals(GENERATE_CLASS)) { new ClassDiagramConverter().createClassDiagrams(ClassChooser.getFilesToOpen()); } else if (menuItem.equals(GENERATE_CLASS_OPTIONS)) { GenerateOptionPanel.getInstance().showPanel(); } else if (menuItem.equals(SAVE) && diagramHandler != null) { diagramHandler.doSave(); } else if (menuItem.equals(SAVE_AS) && diagramHandler != null) { diagramHandler.doSaveAs(Program.getInstance().getExtension()); } else if (menuItem.equals(EXPORT_AS) && diagramHandler != null) { diagramHandler.doSaveAs((String) param); } else if (menuItem.equals(MAIL_TO)) { gui.setMailPanelEnabled(!gui.isMailPanelVisible()); } else if (menuItem.equals(EDIT_CURRENT_PALETTE)) { main.doOpen(main.getPalette().getFileHandler().getFullPathName()); } else if (menuItem.equals(OPTIONS)) { OptionPanel.getInstance().showOptionPanel(); } else if (menuItem.equals(PRINT) && diagramHandler != null) { diagramHandler.doPrint(); } else if (menuItem.equals(EXIT)) { CurrentGui.getInstance().getGui().closeWindow(); } else if (menuItem.equals(UNDO) && actualHandler != null && actualSelector != null) { actualHandler.getController().undo(); } else if (menuItem.equals(REDO) && actualHandler != null) { actualHandler.getController().redo(); } else if (menuItem.equals(DELETE) && actualHandler != null && actualSelector != null) { List v = actualSelector.getSelectedElements(); if (v.size() > 0) { actualHandler.getController().executeCommand(new RemoveElement(v)); } } else if (menuItem.equals(SELECT_ALL) && actualHandler != null && actualSelector != null) { actualSelector.selectAll(); } else if (menuItem.equals(GROUP) && actualHandler != null && actualSelector != null) { actualHandler.getController().executeCommand(new ChangeElementSetting(GroupFacet.KEY, actualSelector.getUnusedGroup().toString(), actualSelector.getSelectedElements())); } else if (menuItem.equals(UNGROUP) && actualHandler != null && actualSelector != null) { actualHandler.getController().executeCommand(new ChangeElementSetting(GroupFacet.KEY, null, actualSelector.getSelectedElements())); } else if (menuItem.equals(CUT) && actualHandler != null) { if (!actualHandler.getDrawPanel().getGridElements().isEmpty()) { actualHandler.getController().executeCommand(new Cut()); } } else if (menuItem.equals(COPY) && actualHandler != null) { if (!actualHandler.getDrawPanel().getGridElements().isEmpty()) { actualHandler.getController().executeCommand(new Copy()); } } else if (menuItem.equals(PASTE) && actualHandler != null) { actualHandler.getController().executeCommand(new Paste()); } else if (menuItem.equals(NEW_CE)) { if (gui.getCurrentCustomHandler().closeEntity()) { gui.setCustomPanelEnabled(true); gui.getCurrentCustomHandler().getPanel().setCustomElementIsNew(true); gui.getCurrentCustomHandler().newEntity(); } } else if (menuItem.equals(NEW_FROM_TEMPLATE)) { if (gui.getCurrentCustomHandler().closeEntity()) { gui.setCustomPanelEnabled(true); gui.getCurrentCustomHandler().getPanel().setCustomElementIsNew(true); gui.getCurrentCustomHandler().newEntity((String) param); } } else if (menuItem.equals(EDIT_SELECTED)) { GridElement entity = main.getEditedGridElement(); if (entity != null && entity instanceof CustomElement) { if (gui.getCurrentCustomHandler().closeEntity()) { gui.setCustomPanelEnabled(true); gui.getCurrentCustomHandler().getPanel().setCustomElementIsNew(false); gui.getCurrentCustomHandler().editEntity((CustomElement) entity); } } } else if (menuItem.equals(CUSTOM_ELEMENTS_TUTORIAL)) { BrowserLauncher.openURL(CUSTOM_ELEMENTS_TUTORIAL_URL); } else if (menuItem.equals(ONLINE_HELP)) { BrowserLauncher.openURL(Program.getInstance().getWebsite() + "/faq.htm"); } else if (menuItem.equals(ONLINE_SAMPLE_DIAGRAMS)) { BrowserLauncher.openURL("http://www.itmeyer.at/umlet/uml2/"); } else if (menuItem.equals(VIDEO_TUTORIAL)) { BrowserLauncher.openURL("http://www.youtube.com/watch?v=3UHZedDtr28"); } else if (menuItem.equals(PROGRAM_HOMEPAGE)) { BrowserLauncher.openURL(Program.getInstance().getWebsite()); } else if (menuItem.equals(RATE_PROGRAM)) { BrowserLauncher.openURL("http://marketplace.eclipse.org/content/umlet-uml-tool-fast-uml-diagrams"); } else if (menuItem.equals(ABOUT_PROGRAM)) { AboutDialog.show(); } else if (menuItem.equals(SET_FOREGROUND_COLOR) && actualHandler != null && actualSelector != null) { actualHandler.getController().executeCommand(new ChangeElementSetting(FacetConstants.FOREGROUND_COLOR_KEY, (String) param, actualSelector.getSelectedElements())); } else if (menuItem.equals(SET_BACKGROUND_COLOR) && actualHandler != null && actualSelector != null) { actualHandler.getController().executeCommand(new ChangeElementSetting(FacetConstants.BACKGROUND_COLOR_KEY, (String) param, actualSelector.getSelectedElements())); } else if (menuItem.equals(ALIGN) && actualHandler != null && actualSelector != null) { List v = actualSelector.getSelectedElements(); if (v.size() > 0) { actualHandler.getController().executeCommand(new Align(v, actualSelector.getDominantEntity(), (String) param)); } } else if (menuItem.equals(LAYER) && actualHandler != null && actualSelector != null) { int change = param.equals(LAYER_DOWN) ? -1 : +1; Map valueMap = new HashMap(); for (GridElement e : actualSelector.getSelectedElements()) { valueMap.put(e, Integer.toString(e.getLayer() + change)); } actualHandler.getController().executeCommand(new ChangeElementSetting(LayerFacet.KEY, valueMap)); } } }); } // These components should only be enabled if the drawpanel is not empty protected List diagramDependendComponents = new ArrayList(); public void updateDiagramDependendComponents() { DrawPanel currentDiagram = CurrentGui.getInstance().getGui().getCurrentDiagram(); if (currentDiagram == null) { return; // Possible if method is called at loading a palette } DiagramHandler handler = currentDiagram.getHandler(); boolean enable = !(handler == null || handler.getDrawPanel().getGridElements().isEmpty()); for (JComponent component : diagramDependendComponents) { component.setEnabled(enable); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/JLink.java0000644000175000017500000000132212533641120022222 0ustar benbenpackage com.baselet.gui; import java.awt.Cursor; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JLabel; public class JLink extends JLabel { /** * */ private static final long serialVersionUID = 1L; private String url; public JLink(String url, String text) { super("" + text + ""); this.url = url; setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); setToolTipText(url); addMouseListener(new LinkMouseAdapter()); } private class LinkMouseAdapter extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() > 0) { BrowserLauncher.openURL(url); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/pane/0000755000175000017500000000000012533641120021275 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/pane/OwnTokenMaker.java0000644000175000017500000000454312533641120024672 0ustar benben/* Based on WindowsBatchTokenMaker.java - Scanner for Windows batch files. This library is distributed under a modified BSD license. See the included RSyntaxTextArea.License.txt file for details. */ package com.baselet.gui.pane; import javax.swing.text.Segment; import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rsyntaxtextarea.TokenMap; import org.fife.ui.rsyntaxtextarea.TokenTypes; /** * see http://fifesoft.com/rsyntaxtextarea/doc/CustomSyntaxHighlighting.html for more infos about own syntax */ public class OwnTokenMaker extends AbstractTokenMaker { private static TokenMap wordsToHighlight = new TokenMap(); public static void setMyWordsToHighlight(TokenMap myWordsToHighlight) { OwnTokenMaker.wordsToHighlight = myWordsToHighlight; } public static final String ID = "OwnTokenMaker"; @Override public TokenMap getWordsToHighlight() { return wordsToHighlight; } @Override public void addToken(Segment segment, int start, int end, int tokenType, int startOffset) { if (tokenType == TokenTypes.IDENTIFIER) { int value = getWordsToHighlight().get(segment, start, end); if (value != -1) { tokenType = value; } } super.addToken(segment, start, end, tokenType, startOffset); } /** * Returns a list of tokens representing the given text. * Based on http://fifesoft.com/rsyntaxtextarea/doc/CustomSyntaxHighlighting.html but reduced to our highlighting * * @param text The text to break into tokens. * @param startTokenType The token with which to start tokenizing. * @param startOffset The offset at which the line of tokens begins. * @return A linked list of tokens representing text. */ @Override public Token getTokenList(Segment text, int startTokenType, int startOffset) { resetTokenList(); int offset = text.offset; int count = text.count; int end = offset + count; int newStartOffset = startOffset - offset; int currentTokenStart = offset; int currentTokenType = startTokenType; for (int i = offset; i < end; i++) { if (currentTokenType == TokenTypes.NULL) { currentTokenType = TokenTypes.IDENTIFIER; } } addToken(text, currentTokenStart, end - 1, currentTokenType, newStartOffset + currentTokenStart); addNullToken(); return firstToken; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/pane/OwnSyntaxPane.java0000644000175000017500000001233212533641120024717 0ustar benbenpackage com.baselet.gui.pane; import java.awt.Component; import java.awt.FlowLayout; import java.util.ArrayList; import java.util.List; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.ScrollPaneConstants; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.autocomplete.BasicCompletion; import org.fife.ui.autocomplete.DefaultCompletionProvider; import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.TokenMakerFactory; import org.fife.ui.rsyntaxtextarea.TokenMap; import org.fife.ui.rsyntaxtextarea.TokenTypes; import org.fife.ui.rtextarea.RTextScrollPane; import com.baselet.control.basics.Converter; import com.baselet.control.config.DerivedConfig; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.AutocompletionText; public class OwnSyntaxPane { private static final String SEPARATOR = " "; private final DefaultCompletionProvider provider = new DefaultCompletionProvider() { @Override protected boolean isValidChar(char ch) { return ch != ' '; // every character except space can be part of an autocompletion } }; List words = new ArrayList(); JPanel panel; RSyntaxTextArea textArea; RTextScrollPane scrollPane; public OwnSyntaxPane() { panel = new JPanel(new FlowLayout()); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); textArea = new RSyntaxTextArea() { private static final long serialVersionUID = 7431070002967577129L; @Override public void undoLastAction() { CurrentDiagram.getInstance().getDiagramHandler().getController().undo(); } @Override public void redoLastAction() { CurrentDiagram.getInstance().getDiagramHandler().getController().redo(); } }; // Setup highlighting createHightLightMap(); AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance(); atmf.putMapping(OwnTokenMaker.ID, OwnTokenMaker.class.getName()); textArea.setSyntaxEditingStyle(OwnTokenMaker.ID); textArea.getSyntaxScheme().getStyle(TokenTypes.RESERVED_WORD).foreground = Converter.convert(ColorOwn.SYNTAX_HIGHLIGHTING); // Setup autocompletion createAutocompletionCompletionProvider(); AutoCompletion ac = new AutoCompletion(provider); // ac.setShowDescWindow(true); ac.install(textArea); JLabel propertyLabel = new JLabel(" Properties"); propertyLabel.setAlignmentX(Component.LEFT_ALIGNMENT); propertyLabel.setFont(DerivedConfig.getPanelHeaderFont()); panel.add(propertyLabel); textArea.setAntiAliasingEnabled(true); textArea.setFont(DerivedConfig.getPanelContentFont()); scrollPane = new RTextScrollPane(textArea, false); scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); panel.add(scrollPane); textArea.getDocument().putProperty(PlainDocument.tabSizeAttribute, 3); // Reduce tab size } /** * create one per class * @param strings */ private void createAutocompletionCompletionProvider() { provider.clear(); for (AutocompletionText word : words) { provider.addCompletion(new BasicCompletion(provider, word.getText(), word.getInfo()) { @Override public String toString() { if (getShortDescription() == null) { return getInputText(); } return getInputText() + SEPARATOR + getShortDescription(); } }); } } private void createHightLightMap() { TokenMap myWordsToHighlight = new TokenMap(); for (AutocompletionText word : words) { myWordsToHighlight.put(word.getText(), TokenTypes.RESERVED_WORD); } // use ugly static setter because OwnTokenMaker is unfortunately not instantiated by us OwnTokenMaker.setMyWordsToHighlight(myWordsToHighlight); // switch syntaxstyle to null and back to OwnTokenMaker to make sure the wordsToHighlight are reset! textArea.setSyntaxEditingStyle(null); textArea.setSyntaxEditingStyle(OwnTokenMaker.ID); } public String getText() { return textArea.getText(); } public JPanel getPanel() { return panel; } public void invalidate() { panel.invalidate(); } public JTextComponent getTextComponent() { return textArea; } public void switchToElement(GridElement e) { words = e.getAutocompletionList(); setText(e.getPanelAttributes()); } public void switchToNonElement(String text) { words = new ArrayList(); setText(text); } private void setText(String text) { if (!textArea.getText().equals(text)) { textArea.setText(text); // Always set text even if they are equal to trigger correct syntax highlighting (if words to highlight have changed but text not) } textArea.setCaretPosition(0); createHightLightMap(); createAutocompletionCompletionProvider(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/helper/0000755000175000017500000000000012533641120021631 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/gui/helper/PlainColorIcon.java0000644000175000017500000000151112533641120025345 0ustar benbenpackage com.baselet.gui.helper; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import javax.swing.Icon; import com.baselet.control.basics.Converter; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.ColorOwn.Transparency; public class PlainColorIcon implements Icon { private Color color; public PlainColorIcon(String color) { this.color = Converter.convert(ColorOwn.forStringOrNull(color, Transparency.FOREGROUND)); } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Color old_color = g.getColor(); g.setColor(color); g.fillRect(x, y, 10, 10); g.setColor(old_color); } @Override public int getIconWidth() { return 10; } @Override public int getIconHeight() { return 10; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/0000755000175000017500000000000012533641120021172 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/StartUpHelpText.java0000644000175000017500000001376012533641120025124 0ustar benbenpackage com.baselet.diagram; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Scanner; import javax.swing.JEditorPane; import org.apache.log4j.Logger; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Metakey; import com.baselet.control.enums.Program; import com.baselet.control.util.Path; import com.baselet.control.util.Utils; import com.baselet.gui.CurrentGui; import com.baselet.gui.listener.HyperLinkActiveListener; public class StartUpHelpText extends JEditorPane implements ContainerListener, ComponentListener { private static final long serialVersionUID = 1L; static final Logger log = Logger.getLogger(StartUpHelpText.class); private DrawPanel panel; private boolean visible; public StartUpHelpText(DrawPanel panel) { super(); this.panel = panel; // If the GUI is null (e.g.: if main is used in batch mode) the startup help text is not required if (CurrentGui.getInstance().getGui() == null) { return; } panel.addContainerListener(this); panel.addComponentListener(this); addMouseListener(new DelegatingMouseListener()); try { if (UpdateCheckTimerTask.getInstance().getFilename() == null) { showHTML(createTempFileWithText(getDefaultTextWithReplacedSystemspecificMetakeys())); } else { showHTML(UpdateCheckTimerTask.getInstance().getFilename()); } } catch (IOException e) { throw new RuntimeException("Cannot read startup info file"); } } // Must be overwritten to hide the helptext if a the custom elements panel is toggled without elements on the drawpanel @Override public void setEnabled(boolean en) { super.setEnabled(en); if (en && visible) { if (panel.getGridElements().size() == 0) { setVisible(true); } else { visible = false; } } else { visible = isVisible(); setVisible(false); } } static String getStartUpFileName() { return Path.homeProgram() + "html/startuphelp.html"; } private void showHTML(String filename) throws MalformedURLException, IOException { this.setPage(new URL("file:///" + filename)); addHyperlinkListener(new HyperLinkActiveListener()); setEditable(false); setBackground(Color.WHITE); setSelectionColor(getBackground()); setSelectedTextColor(getForeground()); } static String createTempFileWithText(String textToWriteIntoFile) throws IOException { File tempFile = File.createTempFile(Program.getInstance().getProgramName() + "_startupfile", ".html"); tempFile.deleteOnExit(); FileWriter w = new FileWriter(tempFile); w.write(textToWriteIntoFile); w.close(); return tempFile.getAbsolutePath(); } private static String getDefaultTextWithReplacedSystemspecificMetakeys() throws FileNotFoundException { StringBuilder sb = new StringBuilder(""); Scanner sc = null; try { sc = new Scanner(new File(getStartUpFileName())); while (sc.hasNextLine()) { String line = sc.nextLine(); if (SystemInfo.META_KEY == Metakey.CTRL) { line = line.replace(Metakey.CMD.toString(), Metakey.CTRL.toString()); } else if (SystemInfo.META_KEY == Metakey.CMD) { line = line.replace(Metakey.CTRL.toString(), Metakey.CMD.toString()); } sb.append(line).append("\n"); } } finally { if (sc != null) { sc.close(); } } return sb.toString(); } @Override public void componentAdded(ContainerEvent e) { boolean gridElementAdded = panel.getElementToComponent(e.getChild()) != null; if (gridElementAdded) { setVisible(false); } } @Override public void componentRemoved(ContainerEvent e) { if (e.getContainer().getComponentCount() <= 1 && !equals(e.getChild())) { setVisible(true); } } @Override public void componentResized(ComponentEvent arg0) { Dimension size = panel.getSize(); Dimension labelSize = getPreferredSize(); this.setSize(labelSize); int minDistanceFromTop = 25; int labelSizeToSubtract = Math.max(150, labelSize.height); // the upper border of the startup panel is at least 200px over the middle of the screen (necessary to have a good position for small update info windows) this.setLocation(size.width / 2 - labelSize.width / 2, Math.max(minDistanceFromTop, size.height / 2 - labelSizeToSubtract)); } @Override public void paint(Graphics g) { // Subpixel rendering must be disabled for the startuphelp (looks bad) ((Graphics2D) g).setRenderingHints(Utils.getUxRenderingQualityHigh(false)); super.paint(g); ((Graphics2D) g).setRenderingHints(Utils.getUxRenderingQualityHigh(true)); } @Override public void componentHidden(ComponentEvent arg0) {} @Override public void componentMoved(ComponentEvent arg0) {} @Override public void componentShown(ComponentEvent arg0) {} /** * The MouseListener of this JEditorPane just delegates the * MouseEvents up to the DiagramListener of the Handler */ private class DelegatingMouseListener implements MouseListener { @Override public void mouseClicked(MouseEvent e) { panel.getHandler().getListener().mouseClicked(e); } @Override public void mouseEntered(MouseEvent e) { panel.getHandler().getListener().mouseEntered(e); } @Override public void mouseExited(MouseEvent e) { panel.getHandler().getListener().mouseExited(e); } @Override public void mousePressed(MouseEvent e) { panel.getHandler().getListener().mousePressed(e); } @Override public void mouseReleased(MouseEvent e) { panel.getHandler().getListener().mouseReleased(e); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/DrawPanel.java0000644000175000017500000004701412533641120023720 0ustar benbenpackage com.baselet.diagram; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Timer; import java.util.TimerTask; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.RepaintManager; import javax.swing.ScrollPaneConstants; import org.apache.log4j.Logger; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.Config; import com.baselet.control.config.SharedConfig; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; import com.baselet.control.util.Utils; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.element.Relation; import com.baselet.gui.listener.ScrollbarListener; @SuppressWarnings("serial") public class DrawPanel extends JLayeredPane implements Printable { private static final Logger log = Logger.getLogger(DrawPanel.class); private final Point origin; private JScrollPane _scr; private final SelectorOld selector; private final DiagramHandler handler; private final List gridElements = new ArrayList(); public DrawPanel(DiagramHandler handler) { this.handler = handler; // AB: Origin is used to track diagram movement in Cut Command origin = new Point(); setLayout(null); setBackground(Color.WHITE); setOpaque(true); selector = new SelectorOld(this); JScrollPane p = new JScrollPane() { @Override public void setEnabled(boolean en) { super.setEnabled(en); getViewport().getView().setEnabled(en); } }; p.getHorizontalScrollBar().setUnitIncrement(50); // Using mousewheel on bar or click on arrow p.getHorizontalScrollBar().setSize(0, 15); p.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); p.getVerticalScrollBar().setUnitIncrement(50); p.getVerticalScrollBar().setSize(15, 0); p.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); ScrollbarListener sbL = new ScrollbarListener(this); p.getHorizontalScrollBar().addMouseListener(sbL); p.getVerticalScrollBar().addMouseListener(sbL); p.setBorder(null); setScrollPanel(p); if (Program.getInstance().getRuntimeType() != RuntimeType.BATCH) { // Wait until drawpanel is valid (eg: after loading a diagramm) and then update panel and scrollbars // Otherwise palettes which are larger than the viewable area would sometimes not have visible scrollbars until the first click into the palette new Timer("updatePanelAndScrollbars", true).schedule(new TimerTask() { @Override public void run() { if (isValid()) { updatePanelAndScrollbars(); cancel(); } } }, 25, 25); } this.repaint(); // repaint the drawpanel to be sure everything is visible (startuphelp etc) } @Override public void setEnabled(boolean en) { super.setEnabled(en); handler.setEnabled(en); for (Component c : getComponents()) { c.setEnabled(en); } if (en) { setBackground(new Color(255, 255, 255)); } else { setBackground(new Color(235, 235, 235)); } } public DiagramHandler getHandler() { return handler; } private void setScrollPanel(JScrollPane scr) { _scr = scr; scr.setViewportView(this); } public JScrollPane getScrollPane() { return _scr; } /** * Returns the smalles possible rectangle which contains all entities and a border space around it * * @param borderSpace * the borderspace around the rectangle * @param entities * the entities which should be included * @return Rectangle which contains all entities with border space */ public static Rectangle getContentBounds(int borderSpace, Collection entities) { if (entities.size() == 0) { return new Rectangle(0, 0, 0, 0); } int minx = Integer.MAX_VALUE; int miny = Integer.MAX_VALUE; int maxx = 0; int maxy = 0; for (GridElement e : entities) { minx = Math.min(minx, e.getRectangle().x - borderSpace); miny = Math.min(miny, e.getRectangle().y - borderSpace); maxx = Math.max(maxx, e.getRectangle().x + e.getRectangle().width + borderSpace); maxy = Math.max(maxy, e.getRectangle().y + e.getRectangle().height + borderSpace); } return new Rectangle(minx, miny, maxx - minx, maxy - miny); } @Override public int print(Graphics g, PageFormat pageFormat, int pageIndex) { if (pageIndex > 0) { return NO_SUCH_PAGE; } else { Graphics2D g2d = (Graphics2D) g; RepaintManager currentManager = RepaintManager.currentManager(this); currentManager.setDoubleBufferingEnabled(false); Rectangle bounds = getContentBounds(Config.getInstance().getPrintPadding(), getGridElements()); g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); AffineTransform t = g2d.getTransform(); double scale = Math.min(pageFormat.getImageableWidth() / bounds.width, pageFormat.getImageableHeight() / bounds.height); if (scale < 1) { t.scale(scale, scale); g2d.setTransform(t); } g2d.translate(-bounds.x, -bounds.y); paint(g2d); currentManager = RepaintManager.currentManager(this); currentManager.setDoubleBufferingEnabled(true); return PAGE_EXISTS; } } public List getGridElements() { return gridElements; } public List getOldRelations() { return getHelper(Relation.class); } public List getStickables(Collection excludeList) { if (!SharedConfig.getInstance().isStickingEnabled() || handler instanceof PaletteHandler) { return Collections. emptyList(); } List returnList = getHelper(com.baselet.element.relation.Relation.class); returnList.removeAll(excludeList); return returnList; } @SuppressWarnings("unchecked") private List getHelper(Class filtered) { List gridElementsToReturn = new ArrayList(); for (GridElement e : getGridElements()) { if (e.getClass().equals(filtered)) { gridElementsToReturn.add((T) e); } } return gridElementsToReturn; } public SelectorOld getSelector() { return selector; } /** * This method must be called after every "significant change" on the drawpanel. * This doesn't include every increment of dragging an grid element but it should be called after * the grid elements new location is set (= after the mousebutton is released) * It should be called only once after many grid elements have changed and not for each element! * This makes it very hard to call this method by using listeners, therefore it's called explicitly in specific cases. */ public void updatePanelAndScrollbars() { insertUpperLeftWhitespaceIfNeeded(); removeUnnecessaryWhitespaceAroundDiagram(); } /** * If entities are out of the visible drawpanel border on the upper left * corner this method enlarges the drawpanel and displays scrollbars */ private void insertUpperLeftWhitespaceIfNeeded() { Rectangle diaWithoutWhite = getContentBounds(0, getGridElements()); // We must adjust the components and the view by a certain factor int adjustWidth = 0; if (diaWithoutWhite.getX() < 0) { adjustWidth = diaWithoutWhite.getX(); } int adjustHeight = 0; if (diaWithoutWhite.getY() < 0) { adjustHeight = diaWithoutWhite.getY(); } moveOrigin(adjustWidth, adjustHeight); // If any adjustment is needed we move the components and increase the view position if (adjustWidth != 0 || adjustHeight != 0) { for (int i = 0; i < getComponents().length; i++) { Component c = getComponent(i); c.setLocation(handler.realignToGrid(false, c.getX() - adjustWidth), handler.realignToGrid(false, c.getY() - adjustHeight)); } } if (adjustWidth < 0) { setHorizontalScrollbarVisibility(true); } if (adjustHeight < 0) { setVerticalScrollbarVisibility(true); } int width = (int) (_scr.getHorizontalScrollBar().getValue() + getViewableDiagrampanelSize().getWidth() - adjustWidth); int height = (int) (_scr.getVerticalScrollBar().getValue() + getViewableDiagrampanelSize().getHeight() - adjustHeight); setPreferredSize(new Dimension(width, height)); changeViewPosition(-adjustWidth, -adjustHeight); } /** * Changes the viewposition of the drawpanel and recalculates the optimal drawpanelsize */ public void changeViewPosition(int incx, int incy) { Point viewp = _scr.getViewport().getViewPosition(); _scr.getViewport().setViewSize(getPreferredSize()); _scr.getViewport().setViewPosition(new Point(viewp.x + incx, viewp.y + incy)); } /** * If there is a scrollbar visible and a unnecessary whitespace on any border of the diagram * which is not visible (but possibly scrollable by scrollbars) we remove this whitespace */ private void removeUnnecessaryWhitespaceAroundDiagram() { Rectangle diaWithoutWhite = getContentBounds(0, getGridElements()); Dimension viewSize = getViewableDiagrampanelSize(); int horSbPos = _scr.getHorizontalScrollBar().getValue(); int verSbPos = _scr.getVerticalScrollBar().getValue(); horSbPos = handler.realignToGrid(false, horSbPos); verSbPos = handler.realignToGrid(false, verSbPos); int newX = 0; if (_scr.getHorizontalScrollBar().isShowing()) { if (horSbPos > diaWithoutWhite.getX()) { newX = diaWithoutWhite.getX(); } else { newX = horSbPos; } } int newY = 0; if (_scr.getVerticalScrollBar().isShowing()) { if (verSbPos > diaWithoutWhite.getY()) { newY = diaWithoutWhite.getY(); } else { newY = verSbPos; } } int newWidth = (int) (horSbPos + viewSize.getWidth()); // If the diagram exceeds the right viewable border the width must be adjusted if (diaWithoutWhite.getX() + diaWithoutWhite.getWidth() > horSbPos + viewSize.getWidth()) { newWidth = diaWithoutWhite.getX() + diaWithoutWhite.getWidth(); } int newHeight = (int) (verSbPos + viewSize.getHeight()); // If the diagram exceeds the lower viewable border the width must be adjusted if (diaWithoutWhite.getY() + diaWithoutWhite.getHeight() > verSbPos + viewSize.getHeight()) { newHeight = diaWithoutWhite.getY() + diaWithoutWhite.getHeight(); } moveOrigin(newX, newY); for (GridElement ge : getGridElements()) { ge.setLocation(handler.realignToGrid(false, ge.getRectangle().x - newX), handler.realignToGrid(false, ge.getRectangle().y - newY)); } changeViewPosition(-newX, -newY); setPreferredSize(new Dimension(newWidth - newX, newHeight - newY)); checkIfScrollbarsAreNecessary(); } /** * Returns the visible size of the drawpanel */ public Dimension getViewableDiagrampanelSize() { return getVisibleRect().getSize(); } private void checkIfScrollbarsAreNecessary() { /** * Afterwards recheck if scrollbars are necessary * This is needed to avoid appearing scrollbars if the diagramm is on the bottom right */ Rectangle diaWithoutWhite = getContentBounds(0, getGridElements()); Dimension viewSize = getViewableDiagrampanelSize(); boolean vertWasVisible = isVerticalScrollbarVisible(); boolean horWasVisible = isHorizontalScrollbarVisible(); // Only if the scrollbar is visible we must respect its size to calculate the visibility of the scrollbar int verSbWidth = 0; int horSbHeight = 0; if (vertWasVisible) { verSbWidth = _scr.getVerticalScrollBar().getWidth(); } if (horWasVisible) { horSbHeight = _scr.getHorizontalScrollBar().getHeight(); } // If the horizontal scrollbar is on the most left point && the the right end of the diagram without whitespace <= the viewable width incl. the width of the vertical scrollbar we hide the horizontal scrollbar if (_scr.getHorizontalScrollBar().getValue() < handler.getGridSize() && diaWithoutWhite.getX() + diaWithoutWhite.getWidth() <= viewSize.getWidth() + verSbWidth) { setHorizontalScrollbarVisibility(false); } else if (_scr.getHorizontalScrollBar().getValue() < handler.getGridSize() && getViewableDiagrampanelSize().width + _scr.getHorizontalScrollBar().getValue() == diaWithoutWhite.getX() + diaWithoutWhite.getWidth()) { setHorizontalScrollbarVisibility(false); } else { setHorizontalScrollbarVisibility(true); } if (_scr.getVerticalScrollBar().getValue() < handler.getGridSize() && diaWithoutWhite.getY() + diaWithoutWhite.getHeight() <= viewSize.getHeight() + horSbHeight) { setVerticalScrollbarVisibility(false); } else if (_scr.getVerticalScrollBar().getValue() < handler.getGridSize() && getViewableDiagrampanelSize().height + _scr.getVerticalScrollBar().getValue() == diaWithoutWhite.getY() + diaWithoutWhite.getHeight()) { setVerticalScrollbarVisibility(false); } else { setVerticalScrollbarVisibility(true); } // REMOVED TO FIX JUMPING PALETTE ENTRIES AT COPYING/CUTTING // adjust x and y to avoid jumping diagram if both scrollbars were visible and one of them disappears (only in the upper left corner) int adx = 0; int ady = 0; if (_scr.getHorizontalScrollBar().getValue() != 0 && vertWasVisible && !isVerticalScrollbarVisible()) { adx = handler.realignToGrid(false, horSbHeight); } if (_scr.getVerticalScrollBar().getValue() != 0 && horWasVisible && !isHorizontalScrollbarVisible()) { ady = handler.realignToGrid(false, verSbWidth); } if (adx != 0 || ady != 0) { setPreferredSize(new Dimension((int) (getPreferredSize().getWidth() + adx), (int) getPreferredSize().getHeight() + ady)); changeViewPosition(adx, ady); } } private void setHorizontalScrollbarVisibility(boolean visible) { if (visible) { _scr.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); } else { _scr.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); } } private void setVerticalScrollbarVisibility(boolean visible) { if (visible) { _scr.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); } else { _scr.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); } } private boolean isHorizontalScrollbarVisible() { return _scr.getHorizontalScrollBarPolicy() == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS; } private boolean isVerticalScrollbarVisible() { return _scr.getVerticalScrollBarPolicy() == ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS; } private void drawGrid(Graphics2D g2d) { g2d.setColor(Constants.GRID_COLOR); int gridSize = handler.getGridSize(); if (gridSize == 1) { return; // Gridsize 1 would only make the whole screen grey } int width = 2000 + (int) getPreferredSize().getWidth(); int height = 1000 + (int) getPreferredSize().getHeight(); for (int i = gridSize; i < width; i += gridSize) { g2d.drawLine(i, 0, i, height); } for (int i = gridSize; i < height; i += gridSize) { g2d.drawLine(0, i, width, i); } } // private void drawDevHelpLines(Graphics2D g2d) { // g2d.setStroke(Utils.getStroke(LineType.DASHED, 1)); // // g2d.setColor(Color.BLUE); // int w = handler.getDrawPanel().getScrollPane().getViewport().getViewPosition().x; // int h = handler.getDrawPanel().getScrollPane().getViewport().getViewPosition().y; // g2d.drawRect(w, h, w + 2, h + 2); // // g2d.setColor(Color.GRAY); // Dimension dim = getViewableDiagrampanelSize(); // g2d.drawRect(0, 0, (int) dim.getWidth(), (int) dim.getHeight()); // // g2d.setColor(Color.RED); // Dimension dim2 = getPreferredSize(); // g2d.drawRect(0, 0, (int) dim2.getWidth(), (int) dim2.getHeight()); // // g2d.setStroke(Utils.getStroke(LineType.SOLID, 1)); // } @Override protected void paintChildren(Graphics g) { // check if layers have changed and update them for (GridElement ge : gridElements) { if (!ge.getLayer().equals(getLayer((JComponent) ge.getComponent()))) { setLayer((JComponent) ge.getComponent(), ge.getLayer()); } } Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHints(Utils.getUxRenderingQualityHigh(true)); if (Config.getInstance().isShow_grid()) { drawGrid(g2d); } super.paintComponents(g); } /** * AB: Returns a copy of the actual origin zoomed to 100%. * Origin marks a point that tracks changes of the diagram panel size and can * be used to regenerate the original position of entities at the time they have been cut/copied, * etc... * * @return a point that marks the diagram origin at a zoom of 100%. */ public Point getOriginAtDefaultZoom() { Point originCopy = new Point(origin); originCopy.setLocation( origin.x * Constants.DEFAULTGRIDSIZE / handler.getGridSize(), origin.y * Constants.DEFAULTGRIDSIZE / handler.getGridSize()); return originCopy; } /** * AB: Returns a copy of the actual origin. * Origin marks a point that tracks changes of the diagram panel size and can * be used to regenerate the original position of entities at the time they have been cut/copied, * etc... * * @return a point that marks the diagram origin. */ public Point getOrigin() { log.trace("Diagram origin: " + origin); return new Point(origin); } /** * AB: Moves the origin around the given delta x and delta y * This method is mainly used by updatePanelAndScrollBars() to keep track of the panels size changes. */ public void moveOrigin(int dx, int dy) { log.trace("Move origin to: " + origin); origin.translate(handler.realignToGrid(false, dx), handler.realignToGrid(false, dy)); } /** * AB: Zoom the origin from the old grid size to the new grid size * this method is mainly used by the DiagramHandler classes setGridAndZoom method. * * @see DiagramHandler#setGridAndZoom(int) * @param oldGridSize * the old grid size * @param newGridSize * the new grid size */ public void zoomOrigin(int oldGridSize, int newGridSize) { log.trace("Zoom origin to: " + origin); origin.setLocation(origin.x * newGridSize / oldGridSize, origin.y * newGridSize / oldGridSize); } public void removeElement(GridElement gridElement) { gridElements.remove(gridElement); remove((Component) gridElement.getComponent()); } public void addElement(GridElement gridElement) { gridElements.add(gridElement); add((Component) gridElement.getComponent(), gridElement.getLayer()); } public void updateElements() { for (GridElement e : gridElements) { e.updateModelFromText(); } } public GridElement getElementToComponent(Component component) { for (GridElement e : gridElements) { if (e.getComponent().equals(component)) { return e; } } return null; } public void scroll(int amount) { JScrollBar scrollBar = _scr.getVerticalScrollBar(); int increment = scrollBar.getUnitIncrement(); scrollBar.setValue(scrollBar.getValue() + amount * increment); } private DiagramNotification notification; public void setNotification(DiagramNotification newNotification) { if (notification != null) { remove(notification); } notification = newNotification; add(notification); repaint(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/0000755000175000017500000000000012533641120021601 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/OutputHandler.java0000644000175000017500000001654512533641120025255 0ustar benbenpackage com.baselet.diagram.io; import java.awt.Color; import java.awt.Component; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Collection; import javax.imageio.ImageIO; import javax.swing.JLayeredPane; import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen.SVGGraphics2D; import org.sourceforge.jlibeps.epsgraphics.EpsGraphics2D; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Element; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.Config; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.util.Utils; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.ElementFactorySwing; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.OldGridElement; import com.itextpdf.awt.FontMapper; import com.itextpdf.awt.PdfGraphics2D; import com.itextpdf.text.pdf.PdfWriter; public class OutputHandler { private OutputHandler() {} // private constructor to avoid instantiation public static void createAndOutputToFile(String extension, File file, DiagramHandler handler) throws Exception { OutputStream ostream = new FileOutputStream(file); createToStream(extension, ostream, handler); ostream.close(); } public static void createToStream(String extension, OutputStream ostream, DiagramHandler handler) throws Exception { int oldZoom = handler.getGridSize(); handler.setGridAndZoom(Constants.DEFAULTGRIDSIZE, false); // Zoom to the defaultGridsize before execution // if some GridElements are selected, only export them Collection elementsToDraw = handler.getDrawPanel().getSelector().getSelectedElements(); // if nothing is selected, draw everything if (elementsToDraw.isEmpty()) { elementsToDraw = handler.getDrawPanel().getGridElements(); } OutputHandler.exportToOutputStream(extension, ostream, elementsToDraw); handler.setGridAndZoom(oldZoom, false); // Zoom back to the oldGridsize after execution } private static void exportToOutputStream(String extension, OutputStream ostream, Collection entities) throws IOException { for (GridElement ge : entities) { ge.getDeprecatedAddons().doBeforeExport(); } if (extension.equals("eps")) { exportEps(ostream, entities); } else if (extension.equals("pdf")) { exportPdf(ostream, entities); } else if (extension.equals("svg")) { exportSvg(ostream, entities); } else if (isImageExtension(extension)) { exportImg(extension, ostream, entities); } else { throw new IllegalArgumentException(extension + " is an invalid format"); } } private static void exportEps(OutputStream ostream, Collection entities) throws IOException { Rectangle bounds = DrawPanel.getContentBounds(Config.getInstance().getPrintPadding(), entities); EpsGraphics2D graphics2d = new EpsGraphics2D(Program.getInstance().getProgramName() + " Diagram", ostream, 0, 0, bounds.width, bounds.height); setGraphicsBorders(bounds, graphics2d); paintEntitiesIntoGraphics2D(graphics2d, entities); graphics2d.flush(); graphics2d.close(); } private static void exportPdf(OutputStream ostream, Collection entities) throws IOException { try { FontMapper mapper = new PdfFontMapper(); Rectangle bounds = DrawPanel.getContentBounds(Config.getInstance().getPrintPadding(), entities); com.itextpdf.text.Document document = new com.itextpdf.text.Document(new com.itextpdf.text.Rectangle(bounds.getWidth(), bounds.getHeight())); PdfWriter writer = PdfWriter.getInstance(document, ostream); document.open(); Graphics2D graphics2d = new PdfGraphics2D(writer.getDirectContent(), bounds.getWidth(), bounds.getHeight(), mapper); // We shift the diagram to the upper left corner, so we shift it by (minX,minY) of the contextBounds Dimension trans = new Dimension(bounds.getX(), bounds.getY()); graphics2d.translate(-trans.getWidth(), -trans.getHeight()); paintEntitiesIntoGraphics2D(graphics2d, entities); graphics2d.dispose(); document.close(); } catch (com.itextpdf.text.DocumentException e) { throw new IOException(e.getMessage()); } } private static void exportSvg(OutputStream ostream, Collection entities) throws IOException { Rectangle bounds = DrawPanel.getContentBounds(Config.getInstance().getPrintPadding(), entities); DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); org.w3c.dom.Document document = domImpl.createDocument(null, "svg", null); SVGGraphics2D graphics2d = new SVGGraphics2D(document); graphics2d.setSVGCanvasSize(Converter.convert(bounds.getSize())); paintEntitiesIntoGraphics2D(graphics2d, entities); Element root = graphics2d.getRoot(); root.setAttributeNS(null, "viewBox", String.format("%d %d %d %d", bounds.x, bounds.y, bounds.width, bounds.height)); Writer out = new OutputStreamWriter(ostream, "UTF-8"); // Stream out SVG to the standard output using UTF-8 character to byte encoding graphics2d.stream(root, out, false, false); graphics2d.dispose(); } private static void exportImg(String imgType, OutputStream ostream, Collection entities) throws IOException { ImageIO.write(createImageForGridElements(entities), imgType, ostream); ostream.flush(); ostream.close(); } public static BufferedImage createImageForGridElements(Collection entities) { Rectangle bounds = DrawPanel.getContentBounds(Config.getInstance().getPrintPadding(), entities); BufferedImage im = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2d = im.createGraphics(); graphics2d.setRenderingHints(Utils.getUxRenderingQualityHigh(true)); setGraphicsBorders(bounds, graphics2d); paintEntitiesIntoGraphics2D(graphics2d, entities); graphics2d.dispose(); return im; } private static void setGraphicsBorders(Rectangle bounds, Graphics2D graphics2d) { graphics2d.translate(-bounds.x, -bounds.y); graphics2d.clipRect(bounds.x, bounds.y, bounds.width, bounds.height); graphics2d.setColor(Color.white); graphics2d.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); } private static boolean isImageExtension(String ext) { return ImageIO.getImageWritersBySuffix(ext).hasNext(); } public static void paintEntitiesIntoGraphics2D(Graphics2D g2d, Collection entities) { DiagramHandler handler = new DiagramHandler(null); JLayeredPane tempPanel = new JLayeredPane(); for (GridElement entity : entities) { GridElement clone = ElementFactorySwing.createCopy(entity, handler); com.baselet.element.interfaces.Component component = clone.getComponent(); // Issue 138: when PDF and Swing Export draw on (0,0) a part of the drawn image is cut, therefore it's displaced by 0.5px in that case if (component instanceof OldGridElement) { ((OldGridElement) component).translateForExport(); } tempPanel.add((Component) component, clone.getLayer()); } tempPanel.validate(); tempPanel.setBackground(Color.WHITE); tempPanel.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE); tempPanel.update(g2d); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/PdfFontMapper.java0000644000175000017500000000216212533641120025152 0ustar benbenpackage com.baselet.diagram.io; import java.awt.Font; import com.baselet.control.config.Config; import com.itextpdf.awt.DefaultFontMapper; import com.itextpdf.text.pdf.BaseFont; class PdfFontMapper extends DefaultFontMapper { @Override public BaseFont awtToPdf(Font font) { try { Config config = Config.getInstance(); String fontName; // Choose the appropriate PDF export font if (font == null) { fontName = config.getPdfExportFont(); } else if (font.isBold() && !font.isItalic()) { fontName = config.getPdfExportFontBold(); } else if (font.isItalic() && !font.isBold()) { fontName = config.getPdfExportFontItalic(); } else if (font.isBold() && font.isItalic()) { fontName = config.getPdfExportFontBoldItalic(); } else { fontName = config.getPdfExportFont(); } return BaseFont.createFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); } catch (Exception e) { // Fall back to the default mapper return super.awtToPdf(font); } } @Override public Font pdfToAwt(BaseFont font, int size) { return null; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/OpenFileChooser.java0000644000175000017500000000253312533641120025473 0ustar benbenpackage com.baselet.diagram.io; import java.awt.Frame; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import com.baselet.control.config.Config; import com.baselet.control.enums.Program; public class OpenFileChooser { private JFileChooser fileChooser; public OpenFileChooser() { fileChooser = new JFileChooser(Config.getInstance().getOpenFileHome()); fileChooser.setMultiSelectionEnabled(true); fileChooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return f.getName().endsWith("." + Program.getInstance().getExtension()) || f.isDirectory(); } @Override public String getDescription() { return Program.getInstance().getProgramName() + " diagram format (*." + Program.getInstance().getExtension() + ")"; } }); fileChooser.setAcceptAllFileFilterUsed(false); } public List getFilesToOpen(Frame mainFrame) { List fileNames = new ArrayList(); int returnVal = fileChooser.showOpenDialog(mainFrame); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] selectedFiles = fileChooser.getSelectedFiles(); for (File file : selectedFiles) { fileNames.add(file.getAbsolutePath()); } } return fileNames; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/ClassChooser.java0000644000175000017500000000460412533641120025040 0ustar benbenpackage com.baselet.diagram.io; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import com.baselet.control.config.Config; import com.baselet.gui.CurrentGui; public class ClassChooser { private static JFileChooser instance; private static final String ALLOWED_EXTENSIONS = ".*.(java|class)"; private static final int TOO_MANY_FILES = 10; private static JFileChooser getInstance() { if (instance == null) { instance = new JFileChooser(Config.getInstance().getOpenFileHome()); instance.setMultiSelectionEnabled(true); instance.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); instance.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return Pattern.matches(ALLOWED_EXTENSIONS, f.getName()) || f.isDirectory(); } @Override public String getDescription() { return ".java/.class file or directory"; } }); instance.setAcceptAllFileFilterUsed(false); } return instance; } public static List getFilesToOpen() { List fileNames = new ArrayList(); int returnVal = getInstance().showOpenDialog(CurrentGui.getInstance().getGui().getMainFrame()); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] selectedFiles = getInstance().getSelectedFiles(); for (File file : selectedFiles) { searchRecursively(file, fileNames); } Config.getInstance().setOpenFileHome(selectedFiles[0].getParent()); if (fileNames.size() > TOO_MANY_FILES) { returnVal = JOptionPane.showConfirmDialog(CurrentGui.getInstance().getGui().getMainFrame(), "Your selection contains " + fileNames.size() + " files which may " + "clutter up your diagram. Continue?", "Confirm selection", JOptionPane.OK_CANCEL_OPTION); if (returnVal == JOptionPane.CANCEL_OPTION) { fileNames.clear(); } } } return fileNames; } private static void searchRecursively(File file, List fileNames) { if (Pattern.matches(ALLOWED_EXTENSIONS, file.getName())) { fileNames.add(file.getAbsolutePath()); } else if (file.isDirectory()) { File[] files = file.listFiles(); for (File f : files) { searchRecursively(f, fileNames); } } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/InputHandler.java0000644000175000017500000001515712533641120025052 0ustar benbenpackage com.baselet.diagram.io; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.DrawPanel; import com.baselet.element.ElementFactorySwing; import com.baselet.element.NewGridElement; import com.baselet.element.facet.common.GroupFacet; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElementCompiler; import com.baselet.element.old.element.ErrorOccurred; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.HelpPanelChanged; /** * Describes what should happen with parsed elements from the input file * eg: set DiagramHandler variables, create GridElements etc. */ public class InputHandler extends DefaultHandler { private static final String[] oldGridElementPackages = new String[] { "com.baselet.element.old.element", "com.baselet.element.old.allinone", "com.baselet.element.old.custom" }; private static final Logger log = Logger.getLogger(InputHandler.class); private DrawPanel _p = null; private GridElement e = null; private String elementtext; private int x; private int y; private int w; private int h; private String entityname; private String code; private String panel_attributes; private String additional_attributes; private Integer currentGroup; private final DiagramHandler handler; // to be backward compatible - add list of old elements that were removed so that they are ignored when loading old files private final List ignoreElements; private String id; // Experimental elements have an id instead of an entityname public InputHandler(DiagramHandler handler) { this.handler = handler; _p = handler.getDrawPanel(); ignoreElements = new ArrayList(); ignoreElements.add("main.control.Group"); currentGroup = null; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { elementtext = ""; if (qName.equals("element")) { panel_attributes = ""; additional_attributes = ""; code = null; } if (qName.equals("group")) { // TODO remove group-handling in InputHandler. Until UMLet v13, groups used own element-tags in XML. This has changed to the property group=x, so this handling is only for backwards compatibility currentGroup = handler.getDrawPanel().getSelector().getUnusedGroup(); } } @Override public void endElement(String uri, String localName, String qName) { String elementname = qName; // [UB]: we are not name-space aware, so use the qualified name if (elementname.equals("help_text")) { handler.setHelpText(elementtext); handler.getFontHandler().setDiagramDefaultFontSize(HelpPanelChanged.getFontsize(elementtext)); handler.getFontHandler().setDiagramDefaultFontFamily(HelpPanelChanged.getFontfamily(elementtext)); BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null && gui.getPropertyPane() != null) { // issue 244: in batchmode, a file can have a help_text but gui will be null gui.getPropertyPane().switchToNonElement(elementtext); } } else if (elementname.equals("zoom_level")) { if (handler != null) { handler.setGridSize(Integer.parseInt(elementtext)); } } else if (elementname.equals("group")) { currentGroup = null; } else if (elementname.equals("element")) { if (id != null) { try { NewGridElement e = ElementFactorySwing.create(ElementId.valueOf(id), new Rectangle(x, y, w, h), panel_attributes, additional_attributes, handler); if (currentGroup != null) { e.setProperty(GroupFacet.KEY, currentGroup); } _p.addElement(e); } catch (Exception e) { log.error("Cannot instantiate element with id: " + id, e); } id = null; } else if (!ignoreElements.contains(entityname)) { // OldGridElement handling which can be removed as soon as all OldGridElements have been replaced try { if (code == null) { e = InputHandler.getOldGridElementFromPath(entityname); } else { e = CustomElementCompiler.getInstance().genEntity(code); } } catch (InstantiationException e1) { e = new ErrorOccurred(); } catch (IllegalAccessException e1) { e = new ErrorOccurred(); } catch (ClassNotFoundException e1) { e = new ErrorOccurred(); } e.setRectangle(new Rectangle(x, y, w, h)); e.setPanelAttributes(panel_attributes); e.setAdditionalAttributes(additional_attributes); handler.setHandlerAndInitListeners(e); if (currentGroup != null) { e.setProperty(GroupFacet.KEY, currentGroup); } _p.addElement(e); } } else if (elementname.equals("type")) { entityname = elementtext; } else if (elementname.equals("id")) { // new elements have an id id = elementtext; } else if (elementname.equals("x")) { Integer i = Integer.valueOf(elementtext); x = i.intValue(); } else if (elementname.equals("y")) { Integer i = Integer.valueOf(elementtext); y = i.intValue(); } else if (elementname.equals("w")) { Integer i = Integer.valueOf(elementtext); w = i.intValue(); } else if (elementname.equals("h")) { Integer i = Integer.valueOf(elementtext); h = i.intValue(); } else if (elementname.equals("panel_attributes")) { panel_attributes = elementtext; } else if (elementname.equals("additional_attributes")) { additional_attributes = elementtext; } else if (elementname.equals("custom_code")) { code = elementtext; } } @Override public void characters(char[] ch, int start, int length) { elementtext += new String(ch).substring(start, start + length); } private static GridElement getOldGridElementFromPath(String path) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Class foundClass = null; String className = path.substring(path.lastIndexOf(".")); for (String possPackage : oldGridElementPackages) { try { foundClass = Thread.currentThread().getContextClassLoader().loadClass(possPackage + className); break; } catch (ClassNotFoundException e1) {/* do nothing; try next package */} } if (foundClass == null) { ClassNotFoundException ex = new ClassNotFoundException("class " + path + " not found"); log.error(null, ex); throw ex; } else { return (GridElement) foundClass.newInstance(); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/io/DiagramFileHandler.java0000644000175000017500000003577312533641120026125 0ustar benbenpackage com.baselet.diagram.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.baselet.control.config.Config; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.util.Path; import com.baselet.control.util.RecentlyUsedFilesList; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.Notifier; import com.baselet.element.NewGridElement; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElement; import com.baselet.gui.CurrentGui; public class DiagramFileHandler { private static final Logger log = Logger.getLogger(DiagramFileHandler.class); private String fileName; private final DiagramHandler handler; private File file; private File lastExportFile; private final HashMap filters = new HashMap(); private final HashMap fileextensions = new HashMap(); private final OwnFileFilter filterxml = new OwnFileFilter(Program.getInstance().getExtension(), Program.getInstance().getProgramName() + " diagram format"); private final OwnFileFilter filterbmp = new OwnFileFilter("bmp", "BMP"); private final OwnFileFilter filtereps = new OwnFileFilter("eps", "EPS"); private final OwnFileFilter filtergif = new OwnFileFilter("gif", "GIF"); private final OwnFileFilter filterjpg = new OwnFileFilter("jpg", "JPG"); private final OwnFileFilter filterpdf = new OwnFileFilter("pdf", "PDF"); private final OwnFileFilter filterpng = new OwnFileFilter("png", "PNG"); private final OwnFileFilter filtersvg = new OwnFileFilter("svg", "SVG"); private final OwnFileFilter[] saveFileFilter = new OwnFileFilter[] { filterxml }; private final OwnFileFilter[] exportFileFilter = new OwnFileFilter[] { filterbmp, filtereps, filtergif, filterjpg, filterpdf, filterpng, filtersvg }; private final List allFileFilters = new ArrayList(); protected DiagramFileHandler(DiagramHandler diagramHandler, File file) { handler = diagramHandler; if (file != null) { fileName = file.getName(); } else { fileName = "new." + Program.getInstance().getExtension(); } this.file = file; lastExportFile = file; allFileFilters.addAll(Arrays.asList(saveFileFilter)); allFileFilters.addAll(Arrays.asList(exportFileFilter)); for (OwnFileFilter filter : allFileFilters) { filters.put(filter.getFormat(), filter); fileextensions.put(filter, filter.getFormat()); } } public static DiagramFileHandler createInstance(DiagramHandler diagramHandler, File file) { return new DiagramFileHandler(diagramHandler, file); } private JFileChooser createSaveFileChooser(boolean exportCall) { JFileChooser fileChooser = new JFileChooser(calcInitialDir(exportCall)); fileChooser.setAcceptAllFileFilterUsed(false); // We don't want "all files" as a choice // The input field should show the diagram name as preset fileChooser.setSelectedFile(new File(CurrentDiagram.getInstance().getDiagramHandler().getName())); return fileChooser; } private File calcInitialDir(boolean exportCall) { if (exportCall && lastExportFile != null) { // if this is an export-diagram call the diagram was exported once before (for consecutive export calls - see Issue 82) return lastExportFile; } else if (file != null) { // otherwise if diagram has a fixed uxf path, use this return file; } else { // otherwise use the last used save path return new File(Config.getInstance().getSaveFileHome()); } } public String getFileName() { return fileName; } public String getFullPathName() { if (file != null) { return file.getAbsolutePath(); } return ""; } private void setFileName(String fileName) { this.fileName = fileName; CurrentGui.getInstance().getGui().updateDiagramName(handler, handler.getName()); } private void createXMLOutputDoc(Document doc, Collection elements, Element current) { for (GridElement e : elements) { appendRecursively(doc, current, e); } } private void appendRecursively(Document doc, Element parentXmlElement, GridElement e) { parentXmlElement.appendChild(createXmlElementForGridElement(doc, e)); } private Element createXmlElementForGridElement(Document doc, GridElement e) { // insert normal entity element java.lang.Class c = e.getClass(); String sElType = c.getName(); String sElPanelAttributes = e.getPanelAttributes(); String sElAdditionalAttributes = e.getAdditionalAttributes(); Element el = doc.createElement("element"); if (e instanceof NewGridElement) { Element elType = doc.createElement("id"); elType.appendChild(doc.createTextNode(((NewGridElement) e).getId().toString())); el.appendChild(elType); } else { // OldGridElement Element elType = doc.createElement("type"); elType.appendChild(doc.createTextNode(sElType)); el.appendChild(elType); } Element elCoor = doc.createElement("coordinates"); el.appendChild(elCoor); Element elX = doc.createElement("x"); elX.appendChild(doc.createTextNode("" + e.getRectangle().x)); elCoor.appendChild(elX); Element elY = doc.createElement("y"); elY.appendChild(doc.createTextNode("" + e.getRectangle().y)); elCoor.appendChild(elY); Element elW = doc.createElement("w"); elW.appendChild(doc.createTextNode("" + e.getRectangle().width)); elCoor.appendChild(elW); Element elH = doc.createElement("h"); elH.appendChild(doc.createTextNode("" + e.getRectangle().height)); elCoor.appendChild(elH); Element elPA = doc.createElement("panel_attributes"); elPA.appendChild(doc.createTextNode(sElPanelAttributes)); el.appendChild(elPA); Element elAA = doc.createElement("additional_attributes"); elAA.appendChild(doc.createTextNode(sElAdditionalAttributes)); el.appendChild(elAA); if (e instanceof CustomElement) { Element elCO = doc.createElement("custom_code"); elCO.appendChild(doc.createTextNode(((CustomElement) e).getCode())); el.appendChild(elCO); } return el; } protected String createStringToBeSaved() { DocumentBuilder db = null; String returnString = null; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); Element root = doc.createElement("diagram"); root.setAttribute("program", Program.getInstance().getProgramName().toLowerCase()); root.setAttribute("version", String.valueOf(Program.getInstance().getVersion())); doc.appendChild(root); // save helptext String helptext = handler.getHelpText(); if (!helptext.equals(Constants.getDefaultHelptext())) { Element help = doc.createElement("help_text"); help.appendChild(doc.createTextNode(helptext)); root.appendChild(help); } // save zoom Element zoom = doc.createElement("zoom_level"); zoom.appendChild(doc.createTextNode(String.valueOf(handler.getGridSize()))); root.appendChild(zoom); createXMLOutputDoc(doc, handler.getDrawPanel().getGridElements(), root); // output the stuff... DOMSource source = new DOMSource(doc); StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); transformer.transform(source, result); returnString = stringWriter.toString(); } catch (Exception e) { log.error("Error saving XML.", e); } return returnString; } public void doOpen() { try { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); FileInputStream input = new FileInputStream(file); InputHandler xmlhandler = new InputHandler(handler); parser.parse(input, xmlhandler); input.close(); } catch (Exception e) { log.error("Cannot open the file: " + file.getAbsolutePath(), e); } } public void doSaveAs(String fileextension) throws IOException { boolean ownXmlFormat = fileextension.equals(Program.getInstance().getExtension()); JFileChooser fileChooser = createSaveFileChooser(!ownXmlFormat); String fileName = chooseFileName(ownXmlFormat, filters.get(fileextension), fileChooser); String extension = fileextensions.get(fileChooser.getFileFilter()); if (fileName == null) { return; // If the filechooser has been closed without saving } if (!fileName.endsWith("." + extension)) { fileName += "." + extension; } File fileToSave = new File(fileName); Config.getInstance().setSaveFileHome(fileToSave.getParent()); if (extension.equals(Program.getInstance().getExtension())) { file = fileToSave; setFileName(file.getName()); save(); } else { lastExportFile = fileToSave; doExportAs(extension, fileToSave); } } public File doSaveTempDiagram(String filename, String fileextension) throws IOException { File tempFile = new File(Path.temp() + filename + "." + fileextension); tempFile.deleteOnExit(); if (fileextension.equals(Program.getInstance().getExtension())) { save(tempFile, true); } else { doExportAs(fileextension, tempFile); } return tempFile; } public void doSave() throws IOException { if (file == null || !file.exists()) { doSaveAs(Program.getInstance().getExtension()); } else { save(); } } public void doExportAs(String extension, File file) throws IOException { // CustomElementSecurityManager.addThreadPrivileges(Thread.currentThread(), fileName); try { OutputHandler.createAndOutputToFile(extension, file, handler); } catch (Exception e) { throw new IOException(e.getMessage()); } // CustomElementSecurityManager.remThreadPrivileges(Thread.currentThread()); } private void save() throws UnsupportedEncodingException, FileNotFoundException { save(file, false); // If save is called without a parameter it uses the class variable "file" } private void save(File saveToFile, boolean tempFile) throws UnsupportedEncodingException, FileNotFoundException { String tmp = createStringToBeSaved(); PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(saveToFile), "UTF-8")); out.print(tmp); out.close(); if (!tempFile) { handler.setChanged(false); RecentlyUsedFilesList.getInstance().add(saveToFile.getAbsolutePath()); } Notifier.getInstance().showNotification(saveToFile.getAbsolutePath() + " saved"); } private String chooseFileName(boolean ownXmlFormat, FileFilter filefilter, JFileChooser fileChooser) { String fileName = null; setAvailableFileFilters(ownXmlFormat, fileChooser); fileChooser.setFileFilter(filefilter); int returnVal = fileChooser.showSaveDialog(CurrentGui.getInstance().getGui().getMainFrame()); if (returnVal == JFileChooser.APPROVE_OPTION) { File selectedFileWithExt = getFileWithExtension(fileChooser); if (selectedFileWithExt.exists()) { int overwriteQuestionResult = JOptionPane.showConfirmDialog(CurrentGui.getInstance().getGui().getMainFrame(), "File already exists! Overwrite?", "Overwrite File", JOptionPane.YES_NO_OPTION); if (overwriteQuestionResult == JOptionPane.NO_OPTION) { return chooseFileName(ownXmlFormat, filefilter, fileChooser); } } fileName = selectedFileWithExt.getAbsolutePath(); } return fileName; } /** * If the filename of the filechooser has no extension, the extension from the filefilter is added to the name * @param saveFileChooser2 */ private File getFileWithExtension(JFileChooser fileChooser) { String extension = "." + fileextensions.get(fileChooser.getFileFilter()); String filename = fileChooser.getSelectedFile().getAbsolutePath(); if (!filename.endsWith(extension)) { filename += extension; } File selectedFileWithExt = new File(filename); return selectedFileWithExt; } /** * Updates the available FileFilter to "only uxf/pxf" or "all but uxf/pxf" * * @param ownXmlFormat * If this param is set, only uxf/pxf is visible, otherwise all but uxf/pxf is visible */ private void setAvailableFileFilters(boolean ownXmlFormat, JFileChooser fileChooser) { if (ownXmlFormat) { fileChooser.resetChoosableFileFilters(); fileChooser.addChoosableFileFilter(filterxml); } else { fileChooser.resetChoosableFileFilters(); fileChooser.addChoosableFileFilter(filterbmp); fileChooser.addChoosableFileFilter(filtereps); fileChooser.addChoosableFileFilter(filtergif); fileChooser.addChoosableFileFilter(filterjpg); fileChooser.addChoosableFileFilter(filterpdf); fileChooser.addChoosableFileFilter(filterpng); fileChooser.addChoosableFileFilter(filtersvg); } } protected static class OwnFileFilter extends FileFilter { private final String format; private final String description; protected OwnFileFilter(String format, String description) { this.format = format; this.description = description; } @Override public boolean accept(File f) { return f.getName().endsWith("." + format) || f.isDirectory(); } @Override public String getDescription() { return description + " (*." + format + ")"; } public String getFormat() { return format; } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (file == null ? 0 : file.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } DiagramFileHandler other = (DiagramFileHandler) obj; if (file == null) { if (other.file != null) { return false; } } else if (!file.equals(other.file)) { return false; } return true; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/DiagramPopupMenu.java0000644000175000017500000000223512533641120025254 0ustar benbenpackage com.baselet.diagram; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import com.baselet.gui.menu.MenuFactorySwing; @SuppressWarnings("serial") public class DiagramPopupMenu extends JPopupMenu { public DiagramPopupMenu(boolean extendedForStandaloneGUI) { final MenuFactorySwing menuFactory = MenuFactorySwing.getInstance(); add(menuFactory.createPaste()); if (extendedForStandaloneGUI) { // Extended is true for StandaloneGUI add(menuFactory.createNew()); add(menuFactory.createOpen()); add(menuFactory.createRecentFiles()); add(menuFactory.createSave()); add(menuFactory.createSaveAs()); } add(menuFactory.createExportAs()); add(menuFactory.createMailTo()); add(menuFactory.createPrint()); addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuCanceled(PopupMenuEvent e) {} @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { menuFactory.updateDiagramDependendComponents(); } }); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/SelectorFrame.java0000644000175000017500000000522412533641120024573 0ustar benbenpackage com.baselet.diagram; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JComponent; import org.apache.log4j.Logger; import com.baselet.control.enums.LineType; import com.baselet.control.util.Utils; /** * @author unknown * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ @SuppressWarnings("serial") public class SelectorFrame extends JComponent { private static final Logger log = Logger.getLogger(SelectorFrame.class); // If the frame is drawn from the right to the left or from bottom to top the offset is // the distance from the drawing-start-point to the actual position of the mouse cursor private int offset_left; private int offset_top; // If the lasso is started on an entity the starting position must be displaced by the coordinates of the entity private int entity_displacement_x; private int entity_displacement_y; public SelectorFrame() { super(); reset(); } public void reset() { offset_left = 0; offset_top = 0; entity_displacement_x = 0; entity_displacement_y = 0; } public void setDisplacement(int x, int y) { entity_displacement_x = x; entity_displacement_y = y; } @Override public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.black); g2.setStroke(Utils.getStroke(LineType.DASHED, 1)); g2.drawRect(0, 0, getWidth() - 1, getHeight() - 1); g2.setStroke(Utils.getStroke(LineType.SOLID, 1)); } public void resizeTo(int x, int y) { int locx = getX(); int locy = getY(); int sizx = entity_displacement_x + x - getX(); int sizy = entity_displacement_y + y - getY(); if (sizx - offset_left < 0) { locx += sizx; sizx = sizx * -1 + offset_left; offset_left = sizx; log.trace("LEFT (offset: " + offset_left + "px)"); } else { sizx -= offset_left; locx += offset_left; offset_left = 0; log.trace("RIGHT"); } if (sizy - offset_top < 0) { locy += sizy; sizy = sizy * -1 + offset_top; offset_top = sizy; log.trace("UP (offset: " + offset_top + "px)"); } else { sizy -= offset_top; locy += offset_top; offset_top = 0; log.trace("DOWN"); } log.trace("Starting point: (" + locx + "," + locy + ") Width: " + sizx + ", Height: " + sizy); this.setLocation(locx, locy); this.setSize(sizx, sizy); // TODO Uncomment to see the real lasso border -> remove after implementing lasso on entity // CurrentGui.getInstance().getGUI().getGraphics().drawRect(locx, locy, sizx, sizy); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/PaletteHandler.java0000644000175000017500000000127212533641120024733 0ustar benbenpackage com.baselet.diagram; import java.io.File; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.listener.GridElementListener; import com.baselet.gui.listener.PaletteEntityListener; public class PaletteHandler extends DiagramHandler { public PaletteHandler(File palettefile) { super(palettefile); } @Override public GridElementListener getEntityListener(GridElement e) { return PaletteEntityListener.getInstance(this); } @Override protected void initDiagramPopupMenu(boolean extendedPopupMenu) { /* no diagram popup menu */ } @Override protected void initStartupTextAndFileDrop() { /* no startup and filedrop */ } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/CurrentDiagram.java0000644000175000017500000000146512533641120024752 0ustar benbenpackage com.baselet.diagram; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; public class CurrentDiagram { private final static CurrentDiagram instance = new CurrentDiagram(); public static CurrentDiagram getInstance() { return instance; } private DiagramHandler currentDiagramHandler; // sets the current diagram the user works with - that may be a palette too public void setCurrentDiagramHandler(DiagramHandler handler) { currentDiagramHandler = handler; BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null) { gui.diagramSelected(handler); } } // returns the current diagramhandler the user works with - may be a diagramhandler of a palette too public DiagramHandler getDiagramHandler() { return currentDiagramHandler; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/DiagramNotification.java0000644000175000017500000000411012533641120025744 0ustar benbenpackage com.baselet.diagram; import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import javax.swing.JComponent; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.basics.geom.Rectangle; public class DiagramNotification extends JComponent { private static final long serialVersionUID = 1L; private final String message; private final Rectangle drawPanelSize; private static final Font notificationFont = new Font(Font.SANS_SERIF, Font.PLAIN, 10); private static final FontRenderContext frc = new FontRenderContext(null, true, true); public DiagramNotification(Rectangle drawPanelSize, String message) { this.message = message; this.drawPanelSize = drawPanelSize; this.setSize(100, 20); adaptDimensions(); } @Override public final void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; Composite old = g2.getComposite(); // Store non-transparent composite g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)); // 40% transparency g2.drawRect(0, 0, getWidth() - 1, getHeight() - 1); Font drawFont = g2.getFont(); g2.setFont(notificationFont); adaptDimensions(); int textX = 5; int textY = getHeight() / 2 + 3; g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f)); // 70% transparency g2.drawString(message, textX, textY); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f)); // 5% transparency g2.setColor(java.awt.Color.blue); g2.fillRect(0, 0, getWidth() - 1, getHeight() - 1); g2.setComposite(old); g2.setFont(drawFont); } private void adaptDimensions() { DimensionDouble textSize = FontHandler.getTextSizeStatic(new FormattedFont(message, notificationFont.getSize(), notificationFont, frc)); int x = (int) (drawPanelSize.getX2() - textSize.getWidth() - 20); int y = drawPanelSize.getY() + 10; this.setLocation(x, y); this.setSize((int) textSize.getWidth() + 10, (int) textSize.getHeight() + 10); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/DiagramHandler.java0000644000175000017500000003426012533641120024704 0ustar benbenpackage com.baselet.diagram; import java.awt.Component; import java.awt.MouseInfo; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Vector; import javax.swing.JOptionPane; import org.apache.log4j.Logger; import com.baselet.control.ErrorMessages; import com.baselet.control.Main; import com.baselet.control.SharedUtils; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.Point; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.enums.RuntimeType; import com.baselet.diagram.io.DiagramFileHandler; import com.baselet.element.ComponentSwing; import com.baselet.element.NewGridElement; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.element.Relation; import com.baselet.gui.BaseGUI; import com.baselet.gui.CurrentGui; import com.baselet.gui.command.Controller; import com.baselet.gui.listener.DiagramListener; import com.baselet.gui.listener.GridElementListener; import com.baselet.gui.listener.OldRelationListener; import com.baselet.gui.standalone.FileDrop; import com.baselet.gui.standalone.FileDropListener; import com.baselet.gui.standalone.StandaloneGUI; public class DiagramHandler { private static final Logger log = Logger.getLogger(DiagramHandler.class); private boolean isChanged; private final DiagramFileHandler fileHandler; private final FontHandler fontHandler; protected DrawPanel drawpanel; private final Controller controller; protected DiagramListener listener; private String helptext; private boolean enabled; private int gridSize; private OldRelationListener relationListener; private GridElementListener gridElementListener; public DiagramHandler(File diagram) { this(diagram, false); } protected DiagramHandler(File diagram, boolean nolistener) { gridSize = Constants.DEFAULTGRIDSIZE; isChanged = false; enabled = true; drawpanel = new DrawPanel(this); initStartupTextAndFileDrop(); controller = new Controller(this); fontHandler = new FontHandler(this); fileHandler = DiagramFileHandler.createInstance(this, diagram); if (!nolistener) { setListener(new DiagramListener(this)); } if (diagram != null) { fileHandler.doOpen(); } boolean extendedPopupMenu = false; BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null) { gui.setValueOfZoomDisplay(getGridSize()); if (gui instanceof StandaloneGUI) { extendedPopupMenu = true; // AB: use extended popup menu on standalone gui only } } initDiagramPopupMenu(extendedPopupMenu); } @SuppressWarnings("unused") protected void initStartupTextAndFileDrop() { // If this is not a palette, create a StartupHelpText if (!(this instanceof PaletteHandler)) { StartUpHelpText startupHelpText = new StartUpHelpText(drawpanel); if (Program.getInstance().getRuntimeType() != RuntimeType.BATCH) { // Batchmode doesn't need drag&drop. Also fixes Issue 81 new FileDrop(startupHelpText, new FileDropListener()); } drawpanel.add(startupHelpText); } } protected void initDiagramPopupMenu(boolean extendedPopupMenu) { drawpanel.setComponentPopupMenu(new DiagramPopupMenu(extendedPopupMenu)); } public void setEnabled(boolean en) { if (!en && enabled) { drawpanel.removeMouseListener(listener); drawpanel.removeMouseMotionListener(listener); enabled = false; } else if (en && !enabled) { drawpanel.addMouseListener(listener); drawpanel.addMouseMotionListener(listener); enabled = true; } } protected void setListener(DiagramListener listener) { this.listener = listener; drawpanel.addMouseListener(this.listener); drawpanel.addMouseMotionListener(this.listener); drawpanel.addMouseWheelListener(this.listener); } public DiagramListener getListener() { return listener; } public void setChanged(boolean changed) { if (isChanged != changed) { isChanged = changed; BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null) { gui.setDiagramChanged(this, changed); } } } public DrawPanel getDrawPanel() { return drawpanel; } public DiagramFileHandler getFileHandler() { return fileHandler; } public FontHandler getFontHandler() { return fontHandler; } public Controller getController() { return controller; } // returnvalue needed for eclipse plugin // returns true if the file is saved, else returns false public boolean doSave() { try { fileHandler.doSave(); reloadPalettes(); CurrentGui.getInstance().getGui().afterSaving(); return true; } catch (IOException e) { log.error(e); Main.getInstance().displayError(ErrorMessages.ERROR_SAVING_FILE + e.getMessage()); return false; } } public void doSaveAs(String extension) { if (drawpanel.getGridElements().isEmpty()) { Main.getInstance().displayError(ErrorMessages.ERROR_SAVING_EMPTY_DIAGRAM); } else { try { fileHandler.doSaveAs(extension); reloadPalettes(); CurrentGui.getInstance().getGui().afterSaving(); } catch (IOException e) { log.error(e); Main.getInstance().displayError(ErrorMessages.ERROR_SAVING_FILE + e.getMessage()); } } } public void doPrint() { PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setPrintable(getDrawPanel()); if (printJob.printDialog()) { try { printJob.print(); } catch (PrinterException pe) { Main.getInstance().displayError(ErrorMessages.ERROR_PRINTING); } } } // reloads the diagram from file + updates gui public void reload() { drawpanel.removeAll(); fileHandler.doOpen(); drawpanel.updatePanelAndScrollbars(); } // reloads palettes if the palette has been changed. private void reloadPalettes() { for (DiagramHandler d : Main.getInstance().getPalettes().values()) { if (d.getFileHandler().equals(getFileHandler()) && !d.equals(this)) { d.reload(); } } getDrawPanel().getSelector().updateSelectorInformation(); // Must be updated to remain in the current Property Panel } public void doClose() { if (askSaveIfDirty()) { Main.getInstance().getDiagrams().remove(this); CurrentGui.getInstance().getGui().close(this); drawpanel.getSelector().deselectAll(); // update property panel to now selected diagram (or to empty if no diagram exists) DiagramHandler newhandler = CurrentDiagram.getInstance().getDiagramHandler(); // if (newhandler != null) { newhandler.getDrawPanel().getSelector().updateSelectorInformation(); } else { Main.getInstance().setPropertyPanelToGridElement(null); } } } public String getName() { String name = fileHandler.getFileName(); if (name.contains(".")) { name = name.substring(0, name.lastIndexOf(".")); } return name; } public String getFullPathName() { return fileHandler.getFullPathName(); } public GridElementListener getEntityListener(GridElement e) { if (e instanceof Relation) { if (relationListener == null) { relationListener = new OldRelationListener(this); } return relationListener; } else { if (gridElementListener == null) { gridElementListener = new GridElementListener(this); } return gridElementListener; } } public boolean askSaveIfDirty() { if (isChanged) { int ch = JOptionPane.showOptionDialog(CurrentGui.getInstance().getGui().getMainFrame(), "Save changes?", Program.getInstance().getProgramName() + " - " + getName(), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null); if (ch == JOptionPane.YES_OPTION) { doSave(); return true; } else if (ch == JOptionPane.NO_OPTION) { return true; } return false; } return true; } public void setHelpText(String helptext) { this.helptext = helptext; } public String getHelpText() { if (helptext == null) { return Constants.getDefaultHelptext(); } else { return helptext; } } public boolean isChanged() { return isChanged; } public int getGridSize() { return gridSize; } public float getZoomFactor() { return (float) getGridSize() / (float) Constants.DEFAULTGRIDSIZE; } public void setGridSize(int gridSize) { this.gridSize = gridSize; } public int realignToGrid(double val) { return realignToGrid(true, val, false); } public int realignToGrid(boolean logRealign, double val) { return realignToGrid(logRealign, val, false); } public int realignToGrid(boolean logRealign, double val, boolean roundUp) { return SharedUtils.realignTo(logRealign, val, roundUp, gridSize); } public static int realignTo(int val, int toVal) { return SharedUtils.realignTo(false, val, false, toVal); } public static void zoomEntity(int fromFactor, int toFactor, GridElement e) { Vector vec = new Vector(); vec.add(e); zoomEntities(fromFactor, toFactor, vec); } public static void zoomEntities(int fromFactor, int toFactor, List selectedEntities) { /** * The entities must be resized to the new factor */ for (GridElement entity : selectedEntities) { int newX = entity.getRectangle().x * toFactor / fromFactor; int newY = entity.getRectangle().y * toFactor / fromFactor; int newW = entity.getRectangle().width * toFactor / fromFactor; int newH = entity.getRectangle().height * toFactor / fromFactor; entity.setLocation(realignTo(newX, toFactor), realignTo(newY, toFactor)); // Normally there should be no realign here but relations and custom elements sometimes must be realigned therefore we don't log it as an error entity.setSize(realignTo(newW, toFactor), realignTo(newH, toFactor)); // Resize the coordinates of the points of the relations if (entity instanceof Relation) { for (Point point : ((Relation) entity).getLinePoints()) { newX = point.getX() * toFactor / fromFactor; newY = point.getY() * toFactor / fromFactor; point.setX(realignTo(newX, toFactor)); point.setY(realignTo(newY, toFactor)); } } } } public void setGridAndZoom(int factor) { setGridAndZoom(factor, true); } public void setGridAndZoom(int factor, boolean manualZoom) { /** * Store the old gridsize and the new one. Furthermore check if the zoom process must be made */ int oldGridSize = getGridSize(); if (factor < 1 || factor > 20) { return; // Only zoom between 10% and 200% is allowed } if (factor == oldGridSize) { return; // Only zoom if gridsize has changed } setGridSize(factor); /** * Zoom entities to the new gridsize */ zoomEntities(oldGridSize, gridSize, getDrawPanel().getGridElements()); // AB: Zoom origin getDrawPanel().zoomOrigin(oldGridSize, gridSize); /** * The zoomed diagram will shrink to the upper left corner and grow to the lower right * corner but we want to have the zoom center in the middle of the actual visible drawpanel * so we have to change the coordinates of the entities again */ if (manualZoom) { // calculate mouse position relative to UMLet scrollpane Point mouseLocation = Converter.convert(MouseInfo.getPointerInfo().getLocation()); Point viewportLocation = Converter.convert(getDrawPanel().getScrollPane().getViewport().getLocationOnScreen()); float x = mouseLocation.x - viewportLocation.x; float y = mouseLocation.y - viewportLocation.y; // And add any space on the upper left corner which is not visible but reachable by scrollbar x += getDrawPanel().getScrollPane().getViewport().getViewPosition().getX(); y += getDrawPanel().getScrollPane().getViewport().getViewPosition().getY(); // The result is the point where we want to center the zoom of the diagram float diffx, diffy; diffx = x - x * gridSize / oldGridSize; diffy = y - y * gridSize / oldGridSize; // AB: Move origin in opposite direction log.debug("diffX/diffY: " + diffx + "/" + diffy); log.debug("Manual Zoom Delta: " + realignToGrid(false, diffx) + "/" + realignToGrid(false, diffy)); getDrawPanel().moveOrigin(realignToGrid(false, -diffx), realignToGrid(false, -diffy)); for (GridElement e : getDrawPanel().getGridElements()) { e.setLocationDifference(realignToGrid(false, diffx), realignToGrid(false, diffy)); } /** * Now we have to do some additional "clean up" stuff which is related to the zoom */ getDrawPanel().updatePanelAndScrollbars(); // Set changed only if diagram is not empty (otherwise no element has been changed) if (!drawpanel.getGridElements().isEmpty()) { setChanged(true); } BaseGUI gui = CurrentGui.getInstance().getGui(); if (gui != null) { gui.setValueOfZoomDisplay(factor); } float zoomFactor = CurrentDiagram.getInstance().getDiagramHandler().getZoomFactor() * 100; String zoomtext; if (CurrentDiagram.getInstance().getDiagramHandler() instanceof PaletteHandler) { zoomtext = "Palette zoomed to " + Integer.toString((int) zoomFactor) + "%"; } else { zoomtext = "Diagram zoomed to " + Integer.toString((int) zoomFactor) + "%"; } Notifier.getInstance().showNotification(zoomtext); } } public void setHandlerAndInitListeners(GridElement element) { if (Main.getHandlerForElement(element) != null) { ((Component) element.getComponent()).removeMouseListener(Main.getHandlerForElement(element).getEntityListener(element)); ((Component) element.getComponent()).removeMouseMotionListener(Main.getHandlerForElement(element).getEntityListener(element)); } Main.setHandlerForElement(element, this); ((Component) element.getComponent()).addMouseListener(Main.getHandlerForElement(element).getEntityListener(element)); ((Component) element.getComponent()).addMouseMotionListener(Main.getHandlerForElement(element).getEntityListener(element)); if (element instanceof NewGridElement) { ((ComponentSwing) element.getComponent()).setHandler(this); } element.updateModelFromText(); // must be updated here because the new handler could have a different zoom level } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/UpdateCheckTimerTask.java0000644000175000017500000000575712533641120026057 0ustar benbenpackage com.baselet.diagram; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Scanner; import java.util.TimerTask; import com.baselet.control.enums.Program; import com.baselet.gui.BrowserLauncher; public class UpdateCheckTimerTask extends TimerTask { private static final UpdateCheckTimerTask instance = new UpdateCheckTimerTask(); private UpdateCheckTimerTask() {} public static UpdateCheckTimerTask getInstance() { return instance; } private String filename; public String getFilename() { return filename; } @Override public void run() { try { String newVersionText = getNewVersionTextWithStartupHtmlFormat(); if (newVersionText != null) { // The text is != null if a new version exists filename = StartUpHelpText.createTempFileWithText(newVersionText); } } catch (Exception e) { StartUpHelpText.log.error("Error at checking for new " + Program.getInstance().getProgramName() + " version", e); } } private static String getNewVersionTextWithStartupHtmlFormat() throws IOException { String textFromURL = getNewVersionTextFromURL(); if (textFromURL == null) { return null; } else { return wrapUpdateTextIntoStartupFileHtmlStyle(textFromURL); } } private static String wrapUpdateTextIntoStartupFileHtmlStyle(String textFromURL) throws FileNotFoundException { StringBuilder sb = new StringBuilder(""); Scanner sc = null; try { sc = new Scanner(new File(StartUpHelpText.getStartUpFileName())); while (sc.hasNextLine()) { String line = sc.nextLine(); if (line.contains("")) { break; } sb.append(line).append("\n"); } sb.append(textFromURL).append(""); } finally { if (sc != null) { sc.close(); } } return sb.toString(); } private static String getNewVersionTextFromURL() throws IOException { String versionText = BrowserLauncher.readURL(Program.getInstance().getWebsite() + "/current_umlet_version_changes.txt"); versionText = versionText.replace("<", "<").replace(">", ">").replace("&", "&").replace("\"", """); // escape html characters for safety String[] splitString = versionText.split("\n"); String actualVersion = splitString[0]; if (Program.getInstance().getVersion().compareTo(actualVersion) >= 0) { return null; // no newer version found } StringBuilder sb = new StringBuilder(""); sb.append("

A new version of ").append(Program.getInstance().getProgramName()).append(" (").append(actualVersion).append(") is available at ").append(Program.getInstance().getWebsite().substring("http://".length())).append("

"); // Every line after the first one describes a feature of the new version and will be listed for (int i = 1; i < splitString.length; i++) { sb.append("

").append(splitString[i]).append("

"); } return sb.toString(); } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/SelectorOld.java0000644000175000017500000001022412533641120024253 0ustar benbenpackage com.baselet.diagram; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; import com.baselet.control.Main; import com.baselet.control.basics.geom.Rectangle; import com.baselet.element.Selector; import com.baselet.element.interfaces.GridElement; import com.baselet.element.old.custom.CustomElement; import com.baselet.gui.CurrentGui; public class SelectorOld extends Selector { private GridElement dominantEntity; private final Vector selectedElements = new Vector(); private final DrawPanel panel; private boolean _selectorframeactive; private final SelectorFrame _selectorframe; public SelectorOld(DrawPanel panel) { this.panel = panel; _selectorframeactive = false; _selectorframe = new SelectorFrame(); } public GridElement getDominantEntity() { if (dominantEntity == null && !selectedElements.isEmpty()) { return selectedElements.firstElement(); } return dominantEntity; } public void setDominantEntity(GridElement dominantEntity) { this.dominantEntity = dominantEntity; } public SelectorFrame getSelectorFrame() { return _selectorframe; } public void setSelectorFrameActive(boolean active) { _selectorframeactive = active; if (!active) { _selectorframe.reset(); } } public boolean isSelectorFrameActive() { return _selectorframeactive; } public void deselectAllWithoutUpdatePropertyPanel() { // copy selected entities, clear list (to let GridElement.isSelected() calls return the correct result) and iterate over list and update selection status of GridElements List listCopy = new ArrayList(selectedElements); selectedElements.clear(); for (GridElement e : listCopy) { e.repaint(); // repaint to make sure now unselected entities are not drawn as selected anymore } dominantEntity = null; } public void selectAll() { select(panel.getGridElements()); } @Override public void doAfterSelectionChanged() { updateSelectorInformation(); } private void updateGUIInformation() { CurrentGui.getInstance().getGui().elementsSelected(selectedElements); boolean customElementSelected = selectedElements.size() == 1 && selectedElements.get(0) instanceof CustomElement; CurrentGui.getInstance().getGui().setCustomElementSelected(customElementSelected); } public void updateSelectorInformation() { GridElement elementForPropPanel = null; if (!selectedElements.isEmpty()) { elementForPropPanel = selectedElements.elementAt(selectedElements.size() - 1); } updateSelectorInformation(elementForPropPanel); } // updates the GUI with the current selector information (that includes the propertypanel) public void updateSelectorInformation(GridElement elementForPropPanel) { // every time something is selected - update the current diagram to this element CurrentDiagram.getInstance().setCurrentDiagramHandler(panel.getHandler()); if (CurrentGui.getInstance().getGui() != null) { updateGUIInformation(); Main.getInstance().setPropertyPanelToGridElement(elementForPropPanel); } } public void multiSelect(Rectangle rect) { for (GridElement e : panel.getGridElements()) { if (e.isInRange(rect)) { select(e); } } } @Override public boolean isSelected(GridElement ge) { boolean isSelected = super.isSelected(ge); return isSelected; } @Override public List getSelectedElements() { return selectedElements; } @Override public List getAllElements() { if (CurrentDiagram.getInstance().getDiagramHandler() == null) { return Collections. emptyList(); } return CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel().getGridElements(); } @Override public void doAfterSelect(GridElement e) { super.doAfterSelect(e); e.repaint(); // element must be repainted if selection state has changed (for selectioncolor) } @Override public void doAfterDeselect(GridElement e) { super.doAfterDeselect(e); e.repaint(); // element must be repainted if selection state has changed (for selectioncolor) } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/draw/0000755000175000017500000000000012533641120022127 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/draw/DoubleStroke.java0000644000175000017500000000133712533641120025400 0ustar benbenpackage com.baselet.diagram.draw; import java.awt.BasicStroke; import java.awt.Shape; import java.awt.Stroke; public class DoubleStroke implements Stroke { private Stroke outerStroke; private Stroke innerStroke; public DoubleStroke(float lineWidth, float distanceBetweenLines, int cap, int join, float miterlimit, float[] dash, float dash_phase) { outerStroke = new BasicStroke(lineWidth + distanceBetweenLines, cap, join, miterlimit, dash, dash_phase); innerStroke = new BasicStroke(lineWidth, cap, join, miterlimit, dash, dash_phase); } @Override public Shape createStrokedShape(Shape s) { Shape outline = outerStroke.createStrokedShape(s); return innerStroke.createStrokedShape(outline); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/draw/swing/0000755000175000017500000000000012533641120023256 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/draw/swing/DrawHandlerSwing.java0000644000175000017500000001561012533641120027327 0ustar benbenpackage com.baselet.diagram.draw.swing; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Arc2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Path2D; import java.awt.geom.RoundRectangle2D; import com.baselet.control.basics.Converter; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.basics.geom.PointDouble; import com.baselet.control.constants.Constants; import com.baselet.control.enums.AlignHorizontal; import com.baselet.control.util.Utils; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.draw.DrawFunction; import com.baselet.diagram.draw.DrawHandler; import com.baselet.diagram.draw.helper.ColorOwn; import com.baselet.diagram.draw.helper.Style; import com.baselet.element.interfaces.GridElement; public class DrawHandlerSwing extends DrawHandler { private Graphics2D g2; protected DiagramHandler handler; private boolean translate; // is used because pdf and svg export cut lines if they are drawn at (0,0) private final GridElement gridElement; public DrawHandlerSwing(GridElement gridElement) { super(); this.gridElement = gridElement; } /** * Java Swing JComponents have a width of w, but only w-1 pixels are drawable * Therefore to draw a rectangle around the whole element, you must call g.drawRect(0,0,w-1,h-1) * To avoid this displacement pixel at every draw method, this method ensures you can never draw outside of the right component border * x is also important for width drawings which don't start at 0 (e.g. Deployment "3-dimensional" Rectangle) */ private double inBorderHorizontal(double width, double x) { return Math.min(gridElement.getRectangle().getWidth() - x - 1, width); } /** * same as above but for vertical points */ private double inBorderVertical(double height, double y) { return Math.min(gridElement.getRectangle().getHeight() - y - 1, height); } public void setHandler(DiagramHandler handler) { this.handler = handler; style = new Style(); resetStyle(); } public void setGraphics(Graphics g) { g2 = (Graphics2D) g; } private double getZoom() { return handler.getZoomFactor(); } @Override public DimensionDouble textDimensionHelper(String text) { boolean specialFontSize = style.getFontSize() != getDefaultFontSize(); if (specialFontSize) { handler.getFontHandler().setFontSize(style.getFontSize()); } DimensionDouble returnVal = handler.getFontHandler().getTextSize(text, false); if (specialFontSize) { handler.getFontHandler().resetFontSize(); } return returnVal; } @Override public double getDefaultFontSize() { return handler.getFontHandler().getFontSize(false); } /* DRAW METHODS */ @Override public void drawArc(double x, double y, double width, double height, double start, double extent, boolean open) { double xZoomed = x * getZoom() + HALF_PX; double yZoomed = y * getZoom() + HALF_PX; int arcType = open ? Arc2D.OPEN : Arc2D.PIE; addShape(new Arc2D.Double(xZoomed, yZoomed, inBorderHorizontal(width * getZoom(), xZoomed), inBorderVertical(height * getZoom(), yZoomed), start, extent, arcType)); } @Override public void drawCircle(double x, double y, double radius) { double widthAndHeight = radius * 2; drawEllipse(x - radius, y - radius, widthAndHeight, widthAndHeight); } @Override public void drawEllipse(double x, double y, double width, double height) { double xZoomed = x * getZoom() + HALF_PX; double yZoomed = y * getZoom() + HALF_PX; addShape(new Ellipse2D.Double(xZoomed, yZoomed, inBorderHorizontal(width * getZoom(), xZoomed), inBorderVertical(height * getZoom(), yZoomed))); } @Override public void drawLines(PointDouble... points) { if (points.length > 0) { Path2D.Double path = new Path2D.Double(); boolean first = true; for (PointDouble p : points) { Double x = inBorderHorizontal(Double.valueOf(p.getX() * getZoom() + HALF_PX), 0); Double y = inBorderVertical(Double.valueOf(p.getY() * getZoom() + HALF_PX), 0); if (first) { path.moveTo(x, y); first = false; } else { path.lineTo(x, y); } } // only fill if first point == lastpoint boolean fillShape = points[0].equals(points[points.length - 1]); addShape(path, fillShape); } } @Override public void drawRectangle(double x, double y, double width, double height) { double xZoomed = x * getZoom() + HALF_PX; double yZoomed = y * getZoom() + HALF_PX; addShape(new Rectangle.Double(xZoomed, yZoomed, inBorderHorizontal(width * getZoom(), xZoomed), inBorderVertical(height * getZoom(), yZoomed))); } @Override public void drawRectangleRound(double x, double y, double width, double height, double radius) { double rad = radius * 2 * getZoom(); double xZoomed = x * getZoom() + HALF_PX; double yZoomed = y * getZoom() + HALF_PX; addShape(new RoundRectangle2D.Double(xZoomed, yZoomed, inBorderHorizontal(width * getZoom(), xZoomed), inBorderVertical(height * getZoom(), yZoomed), rad, rad)); } @Override public void printHelper(String text, PointDouble point, AlignHorizontal align) { addText(new Text(text, point.x * getZoom(), point.y * getZoom(), align)); } protected void addShape(final Shape s) { addShape(s, true); } protected void addShape(final Shape s, final boolean fillShape) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { drawShape(styleAtDrawingCall, s, fillShape); } }); } private void drawShape(Style style, Shape s, boolean fillShape) { if (fillShape) { // Shapes Background g2.setColor(Converter.convert(style.getBackgroundColor())); g2.fill(s); } // Shapes Foreground ColorOwn colOwn = getOverlay().getForegroundColor() != null ? getOverlay().getForegroundColor() : style.getForegroundColor(); g2.setColor(Converter.convert(colOwn)); g2.setStroke(Utils.getStroke(style.getLineType(), (float) style.getLineWidth())); if (translate) { double xTranslation = s.getBounds().x == 0 ? Constants.EXPORT_DISPLACEMENT : 0; double yTranslation = s.getBounds().y == 0 ? Constants.EXPORT_DISPLACEMENT : 0; g2.translate(xTranslation, yTranslation); } g2.draw(s); } protected void addText(final Text t) { final Style styleAtDrawingCall = style.cloneFromMe(); addDrawable(new DrawFunction() { @Override public void run() { drawText(styleAtDrawingCall, t); } }); } private void drawText(Style style, Text t) { ColorOwn col = getOverlay().getForegroundColor() != null ? getOverlay().getForegroundColor() : style.getForegroundColor(); g2.setColor(Converter.convert(col)); handler.getFontHandler().setFontSize(style.getFontSize()); g2.setFont(handler.getFontHandler().getFont()); handler.getFontHandler().writeText(g2, t.getText(), t.getX(), t.getY(), t.getHorizontalAlignment()); handler.getFontHandler().resetFontSize(); } public void setTranslate(boolean translate) { this.translate = translate; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/draw/swing/Text.java0000644000175000017500000000115012533641120025042 0ustar benbenpackage com.baselet.diagram.draw.swing; import com.baselet.control.enums.AlignHorizontal; public class Text { private String text; private double x; private double y; private AlignHorizontal horizontalAlignment; public Text(String text, double x, double y, AlignHorizontal align) { this.text = text; this.x = x; this.y = y; horizontalAlignment = align; } public String getText() { return text; } public double getX() { return x; } public double getY() { return y; } public AlignHorizontal getHorizontalAlignment() { return horizontalAlignment; } }umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/Notifier.java0000644000175000017500000000233412533641120023616 0ustar benbenpackage com.baselet.diagram; import java.awt.Rectangle; import java.util.Timer; import java.util.TimerTask; import javax.swing.SwingUtilities; import com.baselet.control.basics.Converter; import com.baselet.control.constants.Constants; public class Notifier { private static final Notifier instance = new Notifier(); public static synchronized Notifier getInstance() { return instance; } public void showNotification(final String message) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { showNotificationHelper(message); } }); } private void showNotificationHelper(String message) { final DrawPanel notifierPanel = CurrentDiagram.getInstance().getDiagramHandler().getDrawPanel(); Rectangle viewRect = notifierPanel.getScrollPane().getViewport().getViewRect(); final DiagramNotification notification = new DiagramNotification(Converter.convert(viewRect), message); new Timer("Notificationtimer", true).schedule(new TimerTask() { @Override public void run() { notifierPanel.remove(notification); notifierPanel.repaint(); } }, Constants.NOTIFICATION_SHOW_TIME); notifierPanel.setNotification(notification); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/FormattedFont.java0000644000175000017500000000504512533641120024615 0ustar benbenpackage com.baselet.diagram; import java.awt.Font; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import com.baselet.control.StringStyle; import com.baselet.control.enums.FormatLabels; public class FormattedFont { private static Integer underline; private static Float bold; private static Float italic; private String string; private final AttributedString atrString; private final FontRenderContext fontRenderContext; private final TextLayout textLayout; public FormattedFont(String text, double fontSize, Font font, FontRenderContext fontRenderContext) { string = setFormatAndRemoveLabels(text); atrString = new AttributedString(string); this.fontRenderContext = fontRenderContext; atrString.addAttribute(TextAttribute.FAMILY, font.getFamily()); atrString.addAttribute(TextAttribute.SIZE, fontSize); atrString.addAttribute(TextAttribute.WEIGHT, bold); atrString.addAttribute(TextAttribute.POSTURE, italic); atrString.addAttribute(TextAttribute.UNDERLINE, underline, 0, string.length()); textLayout = new TextLayout(getAttributedCharacterIterator(), fontRenderContext); } public String getString() { return string; } public void replaceFirstAndLastSpaceWithDot() { if (string.startsWith(" ")) { string = "." + string.substring(1); } if (string.endsWith(" ")) { string = string.substring(string.length() - 1) + "."; } } public FontRenderContext getFontRenderContext() { return fontRenderContext; } public AttributedCharacterIterator getAttributedCharacterIterator() { return atrString.getIterator(); } private static String setFormatAndRemoveLabels(String s) { StringStyle style = StringStyle.analyzeFormatLabels(s); if (style.getFormat().contains(FormatLabels.UNDERLINE)) { underline = TextAttribute.UNDERLINE_ON; } else { underline = -1; // UNDERLINE_OFF } if (style.getFormat().contains(FormatLabels.BOLD)) { bold = TextAttribute.WEIGHT_BOLD; } else { bold = TextAttribute.WEIGHT_REGULAR; } if (style.getFormat().contains(FormatLabels.ITALIC)) { italic = TextAttribute.POSTURE_OBLIQUE; } else { italic = TextAttribute.POSTURE_REGULAR; } return style.getStringWithoutMarkup(); } public double getWidth() { return textLayout.getVisibleAdvance(); } public double getHeight() { return textLayout.getBounds().getHeight(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/FontHandler.java0000644000175000017500000001144012533641120024241 0ustar benbenpackage com.baselet.diagram; import java.awt.Font; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import com.baselet.control.basics.geom.DimensionDouble; import com.baselet.control.config.Config; import com.baselet.control.constants.Constants; import com.baselet.control.enums.AlignHorizontal; public class FontHandler { private final DiagramHandler handler; private Double fontSize; private Double diagramDefaultSize = null; // if "fontsize=..." is uncommented this variable is set private String diagramDefaultFontFamily = null; private FontRenderContext fontrenderContext = new FontRenderContext(null, true, true); public FontHandler(DiagramHandler handler) { this.handler = handler; } public void setFontSize(Double fontsize) { fontSize = fontsize; } public void setDiagramDefaultFontFamily(String fontfamily) { if (Constants.fontFamilyList.contains(fontfamily)) { diagramDefaultFontFamily = fontfamily; } } public void resetDiagramDefaultFontFamily() { diagramDefaultFontFamily = null; } private String getDiagramDefaultFontFamily() { String returnFontFamily; if (diagramDefaultFontFamily != null) { returnFontFamily = diagramDefaultFontFamily; } else { returnFontFamily = Config.getInstance().getDefaultFontFamily(); } return returnFontFamily; } public void setDiagramDefaultFontSize(Double diagramDefaultSize) { this.diagramDefaultSize = diagramDefaultSize; } public void resetFontSize() { fontSize = null; } public void resetDiagramDefaultFontSize() { diagramDefaultSize = null; } public double getFontSize() { return getFontSize(true); } public double getFontSize(boolean applyZoom) { Double returnFontSize; if (fontSize != null) { returnFontSize = fontSize; } else if (diagramDefaultSize != null) { returnFontSize = diagramDefaultSize; } else { returnFontSize = Double.valueOf(Config.getInstance().getDefaultFontsize()); } if (applyZoom) { return returnFontSize * handler.getGridSize() / Constants.DEFAULTGRIDSIZE; } else { return returnFontSize; } } public Font getFont() { return getFont(true); } public Font getFont(boolean applyZoom) { return new Font(getDiagramDefaultFontFamily(), Font.PLAIN, (int) getFontSize(applyZoom)); } public double getDistanceBetweenTexts() { return getDistanceBetweenTexts(true); } public double getDistanceBetweenTexts(boolean applyZoom) { return getFontSize(applyZoom) / 4; } public DimensionDouble getTextSize(String stringWithFormatLabels) { return getTextSize(stringWithFormatLabels, true); } public DimensionDouble getTextSize(String stringWithFormatLabels, boolean applyZoom) { if (stringWithFormatLabels.isEmpty()) { return new DimensionDouble(0, 0); } return FontHandler.getTextSizeStatic(new FormattedFont(stringWithFormatLabels, getFontSize(applyZoom), getFont(applyZoom), fontrenderContext)); } public double getTextWidth(String s) { return getTextWidth(s, true); } public double getTextWidth(String s, boolean applyZoom) { if (s == null) { return 0; } return this.getTextSize(s, applyZoom).getWidth(); } public void writeText(Graphics2D g2, String s, double x, double y, AlignHorizontal align) { writeText(g2, s, x, y, align, true); } public void writeText(Graphics2D g2, String s, double x, double y, AlignHorizontal align, boolean applyZoom) { for (String line : s.split("\n", -1)) { write(g2, line, x, y, align, applyZoom); y += g2.getFontMetrics().getHeight(); } } private void write(Graphics2D g2, String stringWithFormatLabels, double x, double y, AlignHorizontal align, boolean applyZoom) { if (stringWithFormatLabels == null || stringWithFormatLabels.isEmpty()) { return; } double fontSize = getFontSize(applyZoom); FormattedFont formattedFont = new FormattedFont(stringWithFormatLabels, fontSize, getFont(applyZoom), g2.getFontRenderContext()); fontrenderContext = g2.getFontRenderContext(); // TODO workaround to make sure getTextSize works without a graphics object if (align == AlignHorizontal.CENTER) { x = (int) (x - formattedFont.getWidth() / 2); } else if (align == AlignHorizontal.RIGHT) { x = (int) (x - formattedFont.getWidth()); } g2.drawString(formattedFont.getAttributedCharacterIterator(), (float) x, (float) y); } public static DimensionDouble getTextSizeStatic(FormattedFont formattedFont) { // TextLayout trims the string, therefore replace spaces with dots in such cases (dots have exactly the same width as spaces, therefore we will get the expected width WITH spaces) formattedFont.replaceFirstAndLastSpaceWithDot(); TextLayout tl = new TextLayout(formattedFont.getAttributedCharacterIterator(), formattedFont.getFontRenderContext()); return new DimensionDouble(tl.getBounds().getWidth(), tl.getBounds().getHeight()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/diagram/CustomPreviewHandler.java0000644000175000017500000000156512533641120026156 0ustar benbenpackage com.baselet.diagram; import com.baselet.element.interfaces.GridElement; import com.baselet.gui.listener.CustomPreviewEntityListener; import com.baselet.gui.listener.DiagramListener; import com.baselet.gui.listener.GridElementListener; public class CustomPreviewHandler extends DiagramHandler { public CustomPreviewHandler() { super(null, true); setListener(new DiagramListener(this)); } @Override public GridElementListener getEntityListener(GridElement e) { return CustomPreviewEntityListener.getInstance(this); } public void closePreview() { getDrawPanel().getGridElements().clear(); getDrawPanel().removeAll(); } @Override protected void initDiagramPopupMenu(boolean extendedPopupMenu) { /* no diagram popup menu */ } @Override protected void initStartupTextAndFileDrop() { /* no startup and filedrop */ } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/0000755000175000017500000000000012533641120021554 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/0000755000175000017500000000000012533641120022475 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/Method.java0000644000175000017500000000024712533641120024563 0ustar benbenpackage com.baselet.generator.java; public interface Method extends Accessible { String getName(); String getReturnType(); String getSignature(); } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/Field.java0000644000175000017500000000020312533641120024356 0ustar benbenpackage com.baselet.generator.java; public interface Field extends Accessible { String getName(); String getType(); } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/Accessible.java0000644000175000017500000000075412533641120025403 0ustar benbenpackage com.baselet.generator.java; public interface Accessible { public enum AccessFlag { PRIVATE { @Override public String toString() { return "-"; } }, PROTECTED { @Override public String toString() { return "#"; } }, PACKAGE { @Override public String toString() { return "~"; } }, PUBLIC { @Override public String toString() { return "+"; } }; } public AccessFlag getAccess(); } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/bcel/0000755000175000017500000000000012533641120023402 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/bcel/BcelField.java0000644000175000017500000000067512533641120026066 0ustar benbenpackage com.baselet.generator.java.bcel; import org.apache.bcel.classfile.Field; public class BcelField extends BcelAccessible implements com.baselet.generator.java.Field { private Field field; public BcelField(Field field) { super(field); this.field = field; } @Override public String getName() { return field.getName(); } @Override public String getType() { return field.getType().toString(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/bcel/BcelMethod.java0000644000175000017500000000233712533641120026260 0ustar benbenpackage com.baselet.generator.java.bcel; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.Type; public class BcelMethod extends BcelAccessible implements com.baselet.generator.java.Method { private final Method method; private final String className; private boolean isConstructor; public BcelMethod(Method method, String className) { super(method); this.method = method; this.className = className; if (method.getName().equals("") || method.getName().equals("")) { isConstructor = true; } else { isConstructor = false; } } @Override public String getName() { if (isConstructor) { return className; } return method.getName(); } @Override public String getReturnType() { if (isConstructor) { return "ctor"; } return method.getReturnType().toString(); } @Override public String getSignature() { StringBuilder sb = new StringBuilder(""); Type[] arguments = method.getArgumentTypes(); boolean first = true; for (Type argument : arguments) { if (first) { first = false; sb.append(argument); } else { sb.append(", ").append(argument); } } return sb.toString(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/bcel/BcelAccessible.java0000644000175000017500000000116512533641120027073 0ustar benbenpackage com.baselet.generator.java.bcel; import org.apache.bcel.classfile.FieldOrMethod; import com.baselet.generator.java.Accessible; public abstract class BcelAccessible implements Accessible { private AccessFlag flag; public BcelAccessible(FieldOrMethod accessible) { if (accessible.isPrivate()) { flag = AccessFlag.PRIVATE; } else if (accessible.isProtected()) { flag = AccessFlag.PROTECTED; } else if (accessible.isPublic()) { flag = AccessFlag.PUBLIC; } else { flag = AccessFlag.PACKAGE; } } @Override public AccessFlag getAccess() { return flag; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/bcel/BcelJavaClass.java0000644000175000017500000000345412533641120026710 0ustar benbenpackage com.baselet.generator.java.bcel; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.log4j.Logger; public class BcelJavaClass implements com.baselet.generator.java.JavaClass { private static final Logger log = Logger.getLogger(BcelJavaClass.class); private JavaClass clazz; private String className; public BcelJavaClass(String filename) { try { ClassParser parser = new ClassParser(filename); clazz = parser.parse(); } catch (Exception e) { log.error("BCEL library failed to parse " + filename, e); } } @Override public String getName() { String nameWithPackage = clazz.getClassName(); className = nameWithPackage.substring(nameWithPackage.lastIndexOf(".") + 1, nameWithPackage.length()); return className; } @Override public com.baselet.generator.java.Field[] getFields() { Field[] fields = clazz.getFields(); BcelField[] newFields = new BcelField[fields.length]; for (int i = 0; i < fields.length; ++i) { newFields[i] = new BcelField(fields[i]); } return newFields; } @Override public com.baselet.generator.java.Method[] getMethods() { Method[] methods = clazz.getMethods(); BcelMethod[] newMethods = new BcelMethod[methods.length]; for (int i = 0; i < methods.length; ++i) { newMethods[i] = new BcelMethod(methods[i], className); } return newMethods; } @Override public ClassRole getRole() { if (clazz.isInterface()) { return ClassRole.INTERFACE; } else if (clazz.isAbstract()) { return ClassRole.ABSTRACT; } else { return ClassRole.CLASS; } } @Override public String getPackage() { return clazz.getPackageName(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/JavaClass.java0000644000175000017500000000060312533641120025206 0ustar benbenpackage com.baselet.generator.java; public interface JavaClass { public String getName(); public Field[] getFields(); public Method[] getMethods(); public ClassRole getRole(); public enum ClassRole { ABSTRACT, CLASS, INTERFACE; @Override public String toString() { return super.toString().toLowerCase(); } } public String getPackage(); } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/0000755000175000017500000000000012533641120023106 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/JpMethod.java0000644000175000017500000000303612533641120025465 0ustar benbenpackage com.baselet.generator.java.jp; import japa.parser.ast.body.MethodDeclaration; import japa.parser.ast.body.ModifierSet; import japa.parser.ast.body.Parameter; import java.util.List; import com.baselet.generator.java.Method; public class JpMethod implements Method { private final MethodDeclaration method; public JpMethod(MethodDeclaration method) { this.method = method; } @Override public String getName() { return method.getName(); } @Override public String getReturnType() { return method.getType().toString(); } @Override public String getSignature() { List params = null; if ((params = method.getParameters()) == null) { return ""; } StringBuilder sb = new StringBuilder(""); boolean first = true; for (Parameter param : params) { if (first) { first = false; sb.append(param.toString()); } else { sb.append(", ").append(param.toString()); } } return sb.toString(); } @Override /** * Code duplicated in JpConstructor&JpField because the extended class * BodyDeclaration does not provide a getModifiers() method. */ public AccessFlag getAccess() { int modifiers = method.getModifiers(); if ((modifiers & ModifierSet.PUBLIC) != 0) { return AccessFlag.PUBLIC; } else if ((modifiers & ModifierSet.PROTECTED) != 0) { return AccessFlag.PROTECTED; } else if ((modifiers & ModifierSet.PRIVATE) != 0) { return AccessFlag.PRIVATE; } else { return AccessFlag.PACKAGE; } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/JpJavaClass.java0000644000175000017500000000743112533641120026117 0ustar benbenpackage com.baselet.generator.java.jp; import japa.parser.JavaParser; import japa.parser.ast.CompilationUnit; import japa.parser.ast.PackageDeclaration; import japa.parser.ast.body.BodyDeclaration; import japa.parser.ast.body.ClassOrInterfaceDeclaration; import japa.parser.ast.body.ConstructorDeclaration; import japa.parser.ast.body.FieldDeclaration; import japa.parser.ast.body.MethodDeclaration; import japa.parser.ast.body.ModifierSet; import japa.parser.ast.body.TypeDeclaration; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.baselet.generator.java.Field; import com.baselet.generator.java.JavaClass; import com.baselet.generator.java.Method; public class JpJavaClass implements JavaClass { private final Logger log = Logger.getLogger(JpJavaClass.class); private CompilationUnit cu; private final List methods = new ArrayList(); private final List constructors = new ArrayList(); private ClassOrInterfaceDeclaration clazz; private final List fields = new ArrayList(); public JpJavaClass(String filename) throws ClassParserException { FileInputStream in = null; try { in = new FileInputStream(filename); cu = JavaParser.parse(in); } catch (Exception e) { throw new ClassParserException("Javaparser library failed to parse " + filename, e); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { log.error("Exception at Java class parsing", e); } } extractInformation(filename); } private void extractInformation(String filename) throws ClassParserException { List types = cu.getTypes(); for (TypeDeclaration type : types) { if (type instanceof ClassOrInterfaceDeclaration) { clazz = (ClassOrInterfaceDeclaration) type; } List members = type.getMembers(); for (BodyDeclaration member : members) { if (member instanceof FieldDeclaration) { fields.add((FieldDeclaration) member); } else if (member instanceof ConstructorDeclaration) { constructors.add((ConstructorDeclaration) member); } else if (member instanceof MethodDeclaration) { methods.add((MethodDeclaration) member); } } } if (clazz == null) { throw new ClassParserException("Could not successfully parse " + filename + "."); } } @Override public String getName() { return clazz.getName().toString(); } @Override public Field[] getFields() { Field[] newFields = new Field[fields.size()]; int i = 0; for (FieldDeclaration field : fields) { newFields[i] = new JpField(field); i++; } return newFields; } @Override public Method[] getMethods() { Method[] newMethods = new Method[methods.size() + constructors.size()]; int i = 0; for (ConstructorDeclaration constructor : constructors) { newMethods[i] = new JpConstructor(constructor); i++; } for (MethodDeclaration method : methods) { newMethods[i] = new JpMethod(method); i++; } return newMethods; } @Override public ClassRole getRole() { if (clazz.isInterface()) { return ClassRole.INTERFACE; } else if ((clazz.getModifiers() & ModifierSet.ABSTRACT) != 0) { return ClassRole.ABSTRACT; } else { return ClassRole.CLASS; } } @Override public String getPackage() { PackageDeclaration packageDecl = cu.getPackage(); if (packageDecl == null) { return ""; } String packageWithExtra = packageDecl.toString().replace("package ", ""); return packageWithExtra.substring(0, packageWithExtra.lastIndexOf(";")); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/JpConstructor.java0000644000175000017500000000262412533641120026574 0ustar benbenpackage com.baselet.generator.java.jp; import japa.parser.ast.body.ConstructorDeclaration; import japa.parser.ast.body.ModifierSet; import japa.parser.ast.body.Parameter; import java.util.List; import com.baselet.generator.java.Method; public class JpConstructor implements Method { private ConstructorDeclaration constructor; public JpConstructor(ConstructorDeclaration constructor) { this.constructor = constructor; } @Override /** * Code duplicated in JpMethod&JpField because the extended class * BodyDeclaration does not provide a getModifiers() method. */ public AccessFlag getAccess() { int modifiers = constructor.getModifiers(); if ((modifiers & ModifierSet.PUBLIC) != 0) { return AccessFlag.PUBLIC; } else if ((modifiers & ModifierSet.PROTECTED) != 0) { return AccessFlag.PROTECTED; } else if ((modifiers & ModifierSet.PRIVATE) != 0) { return AccessFlag.PRIVATE; } else { return AccessFlag.PACKAGE; } } @Override public String getName() { return constructor.getName(); } @Override public String getReturnType() { return "ctor"; } @Override public String getSignature() { List params = constructor.getParameters(); if (params == null) { return ""; } String paramsWithBraces = params.toString(); return paramsWithBraces.substring(1, paramsWithBraces.length() - 1); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/JpField.java0000644000175000017500000000216312533641120025270 0ustar benbenpackage com.baselet.generator.java.jp; import japa.parser.ast.body.FieldDeclaration; import japa.parser.ast.body.ModifierSet; import com.baselet.generator.java.Field; public class JpField implements Field { private FieldDeclaration field; public JpField(FieldDeclaration field) { this.field = field; } @Override /** * Code duplicated in JpMethod&JpConstructor because the extended class * BodyDeclaration does not provide a getModifiers() method. */ public AccessFlag getAccess() { int modifiers = field.getModifiers(); if ((modifiers & ModifierSet.PUBLIC) != 0) { return AccessFlag.PUBLIC; } else if ((modifiers & ModifierSet.PROTECTED) != 0) { return AccessFlag.PROTECTED; } else if ((modifiers & ModifierSet.PRIVATE) != 0) { return AccessFlag.PRIVATE; } else { return AccessFlag.PACKAGE; } } @Override public String getName() { String varWithBraces = field.getVariables().toString(); return varWithBraces.substring(1, varWithBraces.length() - 1); } @Override public String getType() { return field.getType().toString(); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/java/jp/ClassParserException.java0000644000175000017500000000044312533641120030053 0ustar benbenpackage com.baselet.generator.java.jp; @SuppressWarnings("serial") public class ClassParserException extends Exception { public ClassParserException(String message, Exception e) { super(message, e); } public ClassParserException(String message) { super(message); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/0000755000175000017500000000000012533641120023241 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/Layout.java0000644000175000017500000000433412533641120025365 0ustar benbenpackage com.baselet.generator.sorting; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.diagram.CurrentDiagram; public abstract class Layout { protected final int GRIDSIZE; protected Dimension bounds; public Layout() { GRIDSIZE = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); } public abstract void layout(List elements); public void simpleLayout(Comparator comparator, List elements) { int maxHeight = 0; int sumWidth = 0; for (SortableElement e : elements) { if (e.getElement().getRectangle().height > maxHeight) { maxHeight = e.getElement().getRectangle().height; } sumWidth += e.getElement().getRectangle().width; } // start with a rectangle with one row with all elements in it and determine // the multiplicator by solving: (x / m) / (y * m) = desired relation of width to height double m = Math.sqrt(sumWidth / (0.4 * maxHeight)); int desiredWidth = (int) (sumWidth / m); Collections.sort(elements, comparator); int rows = 1; int curX = GRIDSIZE; int curY = GRIDSIZE; Dimension d = new Dimension(curX, curY); int maxHeightThisRow = 0; for (SortableElement e : elements) { e.getElement().setLocation(curX, curY); if (e.getElement().getRectangle().height > maxHeightThisRow) { maxHeightThisRow = e.getElement().getRectangle().height; } // determine outer x-bounds of all elements placed Rectangle dim = e.getElement().getRectangle(); if (curX + dim.width > d.width) { d.width = curX + e.getElement().getRectangle().width; } if (curX > desiredWidth) { ++rows; curY += maxHeightThisRow + GRIDSIZE; curX = GRIDSIZE; maxHeightThisRow = 0; } else { curX += e.getElement().getRectangle().width + GRIDSIZE; } // determine outer y-bounds of alle elements placed if (elements.indexOf(e) == elements.size() - 1) {// element is the last one d.height = curY + maxHeightThisRow + (rows + 1) * GRIDSIZE; } } d.width += GRIDSIZE; bounds = d; } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/HeightLayout.java0000644000175000017500000000116012533641120026510 0ustar benbenpackage com.baselet.generator.sorting; import java.io.Serializable; import java.util.Comparator; import java.util.List; public class HeightLayout extends Layout { @Override public void layout(List elements) { super.simpleLayout(new HeightSorter(), elements); } private static class HeightSorter implements Comparator, Serializable { private static final long serialVersionUID = 1L; @Override public int compare(SortableElement e1, SortableElement e2) { return e2.getElement().getRectangle().height - e1.getElement().getRectangle().height; } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/AlphabetLayout.java0000644000175000017500000000173612533641120027031 0ustar benbenpackage com.baselet.generator.sorting; import java.io.Serializable; import java.util.Comparator; import java.util.List; import com.baselet.control.config.ConfigClassGen; import com.baselet.generator.java.JavaClass; public class AlphabetLayout extends Layout { @Override public void layout(List elements) { super.simpleLayout(new AlphabetSorter(), elements); } public static String getClassName(JavaClass parsedClass) { String result = ""; if (ConfigClassGen.getInstance().isGenerateClassPackage()) { result += parsedClass.getPackage() + "::"; } result += parsedClass.getName(); return result; } private static class AlphabetSorter implements Comparator, Serializable { private static final long serialVersionUID = 1L; @Override public int compare(SortableElement e1, SortableElement e2) { return getClassName(e1.getParsedClass()).compareTo(getClassName(e2.getParsedClass())); } } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/RelationLayout.java0000644000175000017500000000027512533641120027063 0ustar benbenpackage com.baselet.generator.sorting; import java.util.List; public class RelationLayout extends Layout { @Override public void layout(List elements) {} } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/SortableElement.java0000644000175000017500000000153612533641120027176 0ustar benbenpackage com.baselet.generator.sorting; import com.baselet.element.interfaces.GridElement; import com.baselet.generator.java.JavaClass; public class SortableElement implements Comparable { private final GridElement element; private JavaClass parsedClass; private final String name; public SortableElement(GridElement element, String name) { this.element = element; this.name = name; } public SortableElement(GridElement element, JavaClass parsedClass) { this(element, parsedClass.getPackage()); this.parsedClass = parsedClass; } public GridElement getElement() { return element; } public JavaClass getParsedClass() { return parsedClass; } public String getName() { return name; } @Override public int compareTo(SortableElement o) { return name.compareTo(o.name); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/sorting/PackageLayout.java0000644000175000017500000000545212533641120026643 0ustar benbenpackage com.baselet.generator.sorting; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import com.baselet.control.basics.geom.Dimension; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.enums.ElementId; import com.baselet.diagram.CurrentDiagram; import com.baselet.element.ElementFactorySwing; import com.baselet.element.NewGridElement; public class PackageLayout extends Layout { private final int ADJUST_TO_PACKAGE_HEAD; public PackageLayout() { ADJUST_TO_PACKAGE_HEAD = GRIDSIZE * 2; } @Override public void layout(List elements) { Map> packages = extractPackages(elements); Map> packList = new TreeMap>(); for (Map.Entry> entry : packages.entrySet()) { SortableElement pack = createPackageElement(entry.getKey()); List packElements = entry.getValue(); Layout l = new HeightLayout(); l.layout(packElements); Dimension size = l.bounds; pack.getElement().setSize(size.width, size.height); packList.put(pack, packElements); } Rectangle x = new Rectangle(); for (SortableElement pack : packList.keySet()) { pack.getElement().setLocation(10, 10 + x.y + x.height); x = pack.getElement().getRectangle(); } for (Entry> entry : packList.entrySet()) { adjustLocations(entry.getKey(), entry.getValue()); elements.add(entry.getKey()); } } private void adjustLocations(SortableElement pack, List packElements) { for (SortableElement s : packElements) { Rectangle loc = s.getElement().getRectangle(); Rectangle packLoc = pack.getElement().getRectangle(); s.getElement().setLocation(loc.x + packLoc.x, loc.y + packLoc.y + ADJUST_TO_PACKAGE_HEAD); } } private Map> extractPackages(List elements) { Map> packages = new HashMap>(); for (SortableElement element : elements) { String packageName = element.getParsedClass().getPackage(); if (!packages.containsKey(packageName)) { packages.put(packageName, new ArrayList()); } packages.get(packageName).add(element); } return packages; } private SortableElement createPackageElement(String packageName) { NewGridElement pack = ElementFactorySwing.create(ElementId.UMLPackage, new Rectangle(10, 10, 10, 10), packageName + "\nbg=orange", "", CurrentDiagram.getInstance().getDiagramHandler()); return new SortableElement(pack, packageName); } } umlet-2015-06-03_UMLet_v13.3/Baselet/src/com/baselet/generator/ClassDiagramConverter.java0000644000175000017500000001744612533641120026655 0ustar benbenpackage com.baselet.generator; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.baselet.control.basics.geom.Rectangle; import com.baselet.control.config.ConfigClassGen; import com.baselet.control.enums.ElementId; import com.baselet.control.enums.generator.FieldOptions; import com.baselet.control.enums.generator.MethodOptions; import com.baselet.control.enums.generator.SignatureOptions; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.DiagramHandler; import com.baselet.diagram.FontHandler; import com.baselet.element.ElementFactorySwing; import com.baselet.element.interfaces.GridElement; import com.baselet.generator.java.Accessible.AccessFlag; import com.baselet.generator.java.Field; import com.baselet.generator.java.JavaClass; import com.baselet.generator.java.JavaClass.ClassRole; import com.baselet.generator.java.Method; import com.baselet.generator.java.bcel.BcelJavaClass; import com.baselet.generator.java.jp.ClassParserException; import com.baselet.generator.java.jp.JpJavaClass; import com.baselet.generator.sorting.AlphabetLayout; import com.baselet.generator.sorting.HeightLayout; import com.baselet.generator.sorting.PackageLayout; import com.baselet.generator.sorting.RelationLayout; import com.baselet.generator.sorting.SortableElement; import com.baselet.gui.command.AddElement; /** * Creates a class element from a filename pointing to a .class or .java file according to UML standards, * adds the class to the current diagram and resizes this class element to minimum size where all text is visible. * * @author Lisi Bluemelhuber * */ public class ClassDiagramConverter { private final int GRIDSIZE; public ClassDiagramConverter() { GRIDSIZE = CurrentDiagram.getInstance().getDiagramHandler().getGridSize(); } public void createClassDiagram(String filename) { List fileNames = new ArrayList(); fileNames.add(filename); createClassDiagrams(fileNames); } public void createClassDiagrams(List filesToOpen) { List elements = new ArrayList(); for (String filename : filesToOpen) { SortableElement element = createElement(filename); if (element != null) { elements.add(element); } } switch (ConfigClassGen.getInstance().getGenerateClassSortings()) { case PACKAGE: new PackageLayout().layout(elements); break; case ALPHABET: new AlphabetLayout().layout(elements); break; case RELATIONS: new RelationLayout().layout(elements); break; default: new HeightLayout().layout(elements); // by height } addElementsToDiagram(elements); } private SortableElement createElement(String filename) { JavaClass parsedClass = parseFile(filename); if (parsedClass == null) { return null; } String propertiesText = getElementProperties(parsedClass); List propList = Arrays.asList(propertiesText.split("\n")); Rectangle initialSize = adjustSize(propList); GridElement clazz = ElementFactorySwing.create(ElementId.UMLClass, initialSize, propertiesText, null, CurrentDiagram.getInstance().getDiagramHandler()); return new SortableElement(clazz, parsedClass); } private void addElementsToDiagram(List elements) { DiagramHandler handler = CurrentDiagram.getInstance().getDiagramHandler(); for (SortableElement e : elements) { new AddElement(e.getElement(), handler.realignToGrid(e.getElement().getRectangle().x), handler.realignToGrid(e.getElement().getRectangle().y), false).execute(handler); } handler.setChanged(true); } /** * Adjusts a Class GridElement to the minimum size where all text is visible. * * @param clazz * @return */ private Rectangle adjustSize(List strings) { // GridElement clazz not yet fully initialized, cannot call clazz.getHandler(); FontHandler fontHandler = CurrentDiagram.getInstance().getDiagramHandler().getFontHandler(); int width = 0; int height = strings.size(); double heightTweaker = 0.1; for (String string : strings) { if (string.isEmpty()) { heightTweaker += 1; } else if (string.equals("--")) { heightTweaker += 0.5; } if (fontHandler.getTextWidth(string) > width) { width = (int) (fontHandler.getTextWidth(string) + fontHandler.getDistanceBetweenTexts()) + 10; } } height = (int) (fontHandler.getFontSize() + fontHandler.getDistanceBetweenTexts()) * (height - (int) heightTweaker); return new Rectangle(0, 0, align(width), align(height)); // width&height must be multiples of grid size } private int align(int n) { return n - n % GRIDSIZE + GRIDSIZE; } private String getElementProperties(JavaClass parsedClass) { StringBuilder sb = new StringBuilder(""); createTopSection(parsedClass, sb); sb.append("--\n"); createFieldSection(parsedClass, sb); sb.append("--\n"); createMethodSection(parsedClass, sb); sb.append("--\n"); return sb.toString(); } private void createMethodSection(JavaClass parsedClass, StringBuilder sb) { for (Method method : parsedClass.getMethods()) { if (ConfigClassGen.getInstance().getGenerateClassMethods() == MethodOptions.PUBLIC && method.getAccess() == AccessFlag.PUBLIC) { sb.append(getMethodString(method)); } else if (ConfigClassGen.getInstance().getGenerateClassMethods() == MethodOptions.ALL) { sb.append(getMethodString(method)); } } } private String getMethodString(Method method) { if (ConfigClassGen.getInstance().getGenerateClassSignatures() == SignatureOptions.PARAMS_ONLY) { return method.getAccess() + method.getName() + "(" + method.getSignature() + ")\n"; } else if (ConfigClassGen.getInstance().getGenerateClassSignatures() == SignatureOptions.RETURN_ONLY) { return method.getAccess() + method.getName() + ": " + method.getReturnType() + "\n"; } else { return method.getAccess() + method.getName() + "(" + method.getSignature() + "): " + method.getReturnType() + "\n"; } } private void createFieldSection(JavaClass parsedClass, StringBuilder sb) { for (Field field : parsedClass.getFields()) { if (ConfigClassGen.getInstance().getGenerateClassFields() == FieldOptions.PUBLIC && field.getAccess() == AccessFlag.PUBLIC) { sb.append(field.getAccess()).append(field.getName()).append(": ").append(field.getType()).append("\n"); } else if (ConfigClassGen.getInstance().getGenerateClassFields() == FieldOptions.ALL) { sb.append(field.getAccess()).append(field.getName()).append(": ").append(field.getType()).append("\n"); } } } private void createTopSection(JavaClass parsedClass, StringBuilder sb) { ClassRole role = parsedClass.getRole(); if (role == ClassRole.INTERFACE) { sb.append("<<").append(role).append(">>\n").append(AlphabetLayout.getClassName(parsedClass)); } else if (role == ClassRole.ABSTRACT) { sb.append("/").append(AlphabetLayout.getClassName(parsedClass)).append("/"); } else { sb.append(AlphabetLayout.getClassName(parsedClass)); } sb.append("\n"); } private JavaClass parseFile(String filename) { try { if (getExtension(filename).equals("java")) { return parseJavaFile(filename); } else if (getExtension(filename).equals("class")) { return parseClassFile(filename); } } catch (Exception ignored) {} return null; } private JavaClass parseJavaFile(String filename) { try { return new JpJavaClass(filename); } catch (ClassParserException e) { return null; } } private JavaClass parseClassFile(String filename) { return new BcelJavaClass(filename); } private String getExtension(String filename) { int dotPosition = filename.lastIndexOf("."); return filename.substring(dotPosition + 1, filename.length()); } } umlet-2015-06-03_UMLet_v13.3/Baselet/META-INF/0000755000175000017500000000000012533641120015742 5ustar benbenumlet-2015-06-03_UMLet_v13.3/Baselet/META-INF/MANIFEST.MF0000644000175000017500000000266012533641120017400 0ustar benbenManifest-Version: 1.0 Ant-Version: Apache Ant 1.7.1 Created-By: 14.0-b16 (Sun Microsystems Inc.) Bundle-ManifestVersion: 2 Bundle-Name: Umlet Bundle-SymbolicName: com.umlet.plugin;singleton:=true Bundle-Version: 13.3 Bundle-Activator: com.baselet.plugin.MainPlugin Bundle-Vendor: http://www.umlet.com Require-Bundle: org.eclipse.ui,org.eclipse.ui.ide,org.eclipse.core.res ources,org.eclipse.core.runtime,org.eclipse.jdt.core Bundle-ClassPath: ., lib/autocomplete.jar, lib/batik-awt-util.jar, lib /batik-dom.jar, lib/batik-ext.jar, lib/batik-svggen.jar, lib/batik-ut il.jar, lib/batik-xml.jar, lib/bcel-5.2.jar, lib/commons-io-2.4.jar, lib/itextpdf-5.4.1.jar, lib/javaparser-1.0.8.jar, lib/jlibeps-0.1.jar , lib/log4j-1.2.15.jar, lib/mailapi.jar, lib/org.eclipse.jdt.core.com piler.ecj-4.3.1.jar, lib/rsyntaxtextarea-2.5.2.jar, lib/smtp.jar Main-Class: com.baselet.control.Main Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Eclipse-LazyStart: true Import-Package: org.eclipse.core.filesystem Class-Path: lib/autocomplete.jar lib/batik-awt-util.jar lib/batik-dom. jar lib/batik-ext.jar lib/batik-svggen.jar lib/batik-util.jar lib/bat ik-xml.jar lib/bcel-5.2.jar lib/commons-io-2.4.jar lib/itextpdf-5.4.1 .jar lib/javaparser-1.0.8.jar lib/jlibeps-0.1.jar lib/log4j-1.2.15.ja r lib/mailapi.jar lib/org.eclipse.jdt.core.compiler.ecj-4.3.1.jar lib /rsyntaxtextarea-2.5.2.jar lib/smtp.jar